UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

1,486 lines 150 kB
import { moveItemInArray, CdkDropList, CdkDrag, CdkDragHandle, DragDropModule } from '@angular/cdk/drag-drop';
import * as i0 from '@angular/core';
import { Injectable, forwardRef, Input, Component, EventEmitter, ContentChild, Output, Pipe, Optional, NgModule } from '@angular/core';
import * as i2$1 from '@c8y/ngx-components';
import { gettext, C8yValidators, C8yTranslateDirective, FormGroupComponent, RequiredInputPlaceholderDirective, MessagesComponent, MessageDirective, C8yTranslatePipe, MAX_PAGE_SIZE, IconDirective, ListItemComponent, ListItemDragHandleComponent, ListItemCheckboxComponent, HighlightComponent, ListItemActionComponent, ListItemCollapseComponent, TypeaheadComponent, ForOfDirective, ListItemIconComponent, EmptyStateComponent, LoadingComponent, ListGroupComponent, CoreModule } from '@c8y/ngx-components';
import { MillerViewComponent, AssetSelectorModule } from '@c8y/ngx-components/assets-navigator';
import { CollapseModule } from 'ngx-bootstrap/collapse';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import * as i1$1 from 'ngx-bootstrap/modal';
import { ModalModule } from 'ngx-bootstrap/modal';
import { PopoverDirective, PopoverModule } from 'ngx-bootstrap/popover';
import { TooltipDirective, TooltipModule } from 'ngx-bootstrap/tooltip';
import * as i2 from '@angular/forms';
import { Validators, FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
import { map, take, filter, startWith, tap, switchMap, shareReplay, distinctUntilChanged, debounceTime } from 'rxjs/operators';
import { NgIf, NgFor, NgClass, NgTemplateOutlet, KeyValuePipe, NgSwitch, NgSwitchCase, NgSwitchDefault, AsyncPipe } from '@angular/common';
import * as i4 from '@c8y/ngx-components/context-dashboard';
import { pipe, BehaviorSubject, from, combineLatest } from 'rxjs';
import * as i1 from '@c8y/client';
import { sortBy, get, uniq } from 'lodash-es';

const AXIS_TYPES = [
    { val: undefined, text: gettext('Auto') },
    { val: 'left', text: gettext('Left') },
    { val: 'right', text: gettext('Right') }
];
const CHART_LINE_TYPES = [
    { val: 'line', text: gettext('Line') },
    { val: 'points', text: gettext('Points') },
    { val: 'linePoints', text: gettext('Line and points') },
    { val: 'bars', text: gettext('Bars') },
    { val: 'step-before', text: gettext('Step before') },
    { val: 'step-after', text: gettext('Step after') }
];
const CHART_RENDER_TYPES = [
    { val: 'min', text: gettext('Minimum') },
    { val: 'max', text: gettext('Maximum') },
    { val: 'area', text: gettext('Minimum and maximum') }
];

class DatapointAttributesFormValidationService {
    constructor(formBuilder) {
        this.formBuilder = formBuilder;
    }
    getDefaultFormGroup(fieldsToRemove = []) {
        const formFields = {
            __active: [true, []],
            __target: this.getTargetFormGroup(),
            __template: [undefined, []],
            color: ['', this.getColorValidators()],
            label: ['', this.getLabelValidators()],
            description: ['', this.getDescriptionValidators()],
            fragment: ['', this.getFragmentValidators()],
            series: ['', this.getSeriesValidators()],
            range: this.getMinMaxFormGroup(),
            unit: [undefined, this.getUnitValidators()],
            target: [undefined, this.getTargetValidators()],
            redRange: this.getMinMaxFormGroup(),
            yellowRange: this.getMinMaxFormGroup(),
            chart: this.getChartFormGroup(),
            display: this.getDisplayFormGroup()
        };
        if (fieldsToRemove.length) {
            for (const field of fieldsToRemove) {
                delete formFields[field];
            }
        }
        return this.formBuilder.group(formFields, {
            validators: this.getOverallValidators()
        });
    }
    convertToBackendFormat(formDataStructure, showChart) {
        if (!formDataStructure) {
            return {};
        }
        const { __active, __target, __template, color, label, description, fragment, series, range, unit, target, redRange, yellowRange, chart, display } = formDataStructure;
        const obj = {
            __active,
            __target,
            __template,
            color,
            label,
            description,
            fragment,
            series,
            min: range?.min,
            max: range?.max,
            unit,
            target,
            redRangeMin: redRange?.min,
            redRangeMax: redRange?.max,
            yellowRangeMin: yellowRange?.min,
            yellowRangeMax: yellowRange?.max,
            renderType: showChart ? chart?.renderType : display?.renderType,
            lineType: chart?.lineType,
            yAxisType: chart?.yAxisType
        };
        return obj;
    }
    convertToFormGroupFormat(backendDataStructure) {
        if (!backendDataStructure) {
            return {};
        }
        const { __active, __target, __template, color, label, description, fragment, series, min, max, unit, target, redRangeMin, redRangeMax, yellowRangeMin, yellowRangeMax, renderType, lineType, yAxisType } = backendDataStructure;
        const obj = {
            __active,
            __target,
            __template,
            color,
            label,
            description,
            fragment,
            series,
            range: {
                min: this.convertStringToNumber(min),
                max: this.convertStringToNumber(max)
            },
            unit,
            target: this.convertStringToNumber(target),
            redRange: {
                min: this.convertStringToNumber(redRangeMin),
                max: this.convertStringToNumber(redRangeMax)
            },
            yellowRange: {
                min: this.convertStringToNumber(yellowRangeMin),
                max: this.convertStringToNumber(yellowRangeMax)
            },
            chart: renderType || lineType || yAxisType ? { renderType, lineType, yAxisType } : undefined,
            display: renderType ? { renderType } : undefined
        };
        return obj;
    }
    getColorValidators() {
        return [Validators.required, Validators.minLength(4)];
    }
    getLabelValidators() {
        return [Validators.required, Validators.minLength(1), Validators.maxLength(120)];
    }
    getDescriptionValidators() {
        return [];
    }
    getFragmentValidators() {
        return [
            Validators.required,
            Validators.minLength(1),
            Validators.maxLength(120),
            Validators.pattern(/^[^.]*$/)
        ];
    }
    getSeriesValidators() {
        return [
            Validators.required,
            Validators.minLength(1),
            Validators.maxLength(120),
            (control) => {
                const forbidden = control.value?.includes('.') || '';
                return forbidden
                    ? { noPeriods: { message: gettext('Series cannot contain periods.') } }
                    : null;
            }
        ];
    }
    getMinMaxValidators() {
        return [C8yValidators.minMaxValidator(), C8yValidators.requireBothMinAndMax()];
    }
    getUnitValidators() {
        return [];
    }
    getTargetValidators() {
        return [];
    }
    getOverallValidators() {
        return [
            C8yValidators.withinScale('redRange.min'),
            C8yValidators.withinScale('redRange.max'),
            C8yValidators.withinScale('yellowRange.min'),
            C8yValidators.withinScale('yellowRange.max'),
            C8yValidators.withinScale('target')
        ];
    }
    getMinMaxFormGroup() {
        return this.formBuilder.group({ min: [undefined, []], max: [undefined, []] }, { validators: this.getMinMaxValidators() });
    }
    getChartFormGroup() {
        return this.formBuilder.group({
            renderType: [CHART_RENDER_TYPES[0].val, []],
            lineType: [CHART_LINE_TYPES[0].val, []],
            yAxisType: [AXIS_TYPES[0].val, []]
        });
    }
    getDisplayFormGroup() {
        return this.formBuilder.group({
            renderType: [CHART_RENDER_TYPES[0].val, []]
        });
    }
    getTargetFormGroup() {
        return this.formBuilder.group({
            id: [undefined, []],
            name: [undefined, []]
        });
    }
    convertStringToNumber(possibleString) {
        if (typeof possibleString === 'string') {
            try {
                return Number.parseFloat(possibleString);
            }
            catch {
                return undefined;
            }
        }
        else {
            return possibleString;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointAttributesFormValidationService, deps: [{ token: i2.FormBuilder }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointAttributesFormValidationService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointAttributesFormValidationService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: i2.FormBuilder }] });

class DatapointAttributesFormComponent {
    constructor(formValidations) {
        this.formValidations = formValidations;
        this.selectableChartRenderTypes = [];
        this.selectableChartLineTypes = [];
        this.selectableAxisTypes = [];
        this.showTarget = true;
        this.showRange = true;
        this.showYellowRange = true;
        this.showRedRange = true;
        this.showChart = true;
        this.showFormIfTemplateWasSelected = false;
        this.rawValue = {};
        this.CHART_RENDER_TYPES = Array.from(CHART_RENDER_TYPES);
        this.CHART_LINE_TYPES = Array.from(CHART_LINE_TYPES);
        this.AXIS_TYPES = Array.from(AXIS_TYPES);
        this.customValidationErrorMessages = {};
        this.shouldForceInitialValidation = true;
        this.formGroup = this.formValidations.getDefaultFormGroup();
        this.setSubForms();
    }
    ngOnInit() {
        this.initializeFormVisibility();
        this.filterChartTypes();
    }
    validate(_control) {
        if (this.formGroup?.get('series')?.errors?.noPeriods) {
            return this.formGroup?.get('series')?.errors;
        }
        return this.formGroup?.valid ? null : { formInvalid: {} };
    }
    writeValue(obj) {
        this.rawValue = obj || {};
        if (obj) {
            this.formGroup.patchValue(this.formValidations.convertToFormGroupFormat(obj), {
                emitEvent: false
            });
        }
        if (this.shouldForceInitialValidation) {
            queueMicrotask(() => {
                this.formGroup.updateValueAndValidity();
            });
            this.shouldForceInitialValidation = false;
        }
    }
    registerOnChange(fn) {
        this.formGroup.valueChanges
            .pipe(map(formValue => this.formValidations.convertToBackendFormat(formValue, this.showChart)), map(formValue => Object.assign(this.rawValue, formValue)))
            .subscribe(fn);
    }
    registerOnTouched(fn) {
        this.formGroup.valueChanges.pipe(take(1)).subscribe(fn);
    }
    setDisabledState(isDisabled) {
        if (this.formGroup?.disabled === isDisabled) {
            return;
        }
        isDisabled ? this.formGroup.disable() : this.formGroup.enable();
    }
    setSubForms() {
        if (!this.formGroup) {
            this.range = this.yellowRange = this.redRange = this.chart = undefined;
            return;
        }
        this.range = this.formGroup.get('range');
        this.yellowRange = this.formGroup.get('yellowRange');
        this.redRange = this.formGroup.get('redRange');
        this.chart = this.formGroup.get('chart');
        this.display = this.formGroup.get('display');
    }
    initializeFormVisibility() {
        this.showChartForm = this.chart && this.showChart;
        const hasLineTypes = !!this.selectableChartLineTypes?.length;
        const hasAxisTypes = !!this.selectableAxisTypes?.length;
        const hasRenderTypes = this.selectableChartRenderTypes?.length > 0 || this.selectableChartRenderTypes === undefined;
        this.showOnlyDisplayForm =
            !this.showChartForm && !hasLineTypes && !hasAxisTypes && hasRenderTypes;
    }
    filterChartTypes() {
        this.filterRenderTypes();
        this.filterLineTypes();
        this.filterAxisTypes();
    }
    filterRenderTypes() {
        if (!!this.selectableChartRenderTypes?.length) {
            this.CHART_RENDER_TYPES = this.CHART_RENDER_TYPES.filter(renderType => this.selectableChartRenderTypes.includes(renderType.val));
        }
    }
    filterLineTypes() {
        if (!!this.selectableChartLineTypes?.length) {
            this.CHART_LINE_TYPES = this.CHART_LINE_TYPES.filter(lineType => this.selectableChartLineTypes.includes(lineType.val));
        }
    }
    filterAxisTypes() {
        if (!!this.selectableAxisTypes?.length) {
            this.AXIS_TYPES = this.AXIS_TYPES.filter(axisType => this.selectableAxisTypes.includes(axisType.val));
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointAttributesFormComponent, deps: [{ token: DatapointAttributesFormValidationService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DatapointAttributesFormComponent, isStandalone: true, selector: "c8y-datapoint-attributes-form", inputs: { selectableChartRenderTypes: "selectableChartRenderTypes", selectableChartLineTypes: "selectableChartLineTypes", selectableAxisTypes: "selectableAxisTypes", showTarget: "showTarget", showRange: "showRange", showYellowRange: "showYellowRange", showRedRange: "showRedRange", showChart: "showChart", showFormIfTemplateWasSelected: "showFormIfTemplateWasSelected" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => DatapointAttributesFormComponent),
                multi: true
            },
            {
                provide: NG_VALIDATORS,
                useExisting: forwardRef(() => DatapointAttributesFormComponent),
                multi: true
            }
        ], ngImport: i0, template: "<div [formGroup]=\"formGroup\">\n  <ng-container *ngIf=\"!rawValue?.__template || showFormIfTemplateWasSelected\">\n    <fieldset\n      class=\"c8y-fieldset\"\n      *ngIf=\"formGroup.controls?.label || formGroup.controls?.unit || formGroup.controls?.target\"\n    >\n      <legend translate>Details</legend>\n      <div class=\"row\">\n        <div\n          class=\"col-md-6\"\n          *ngIf=\"formGroup.controls?.label\"\n        >\n          <c8y-form-group class=\"form-group-sm\">\n            <label translate>Label</label>\n            <input\n              class=\"form-control\"\n              name=\"label\"\n              formControlName=\"label\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 'Temperature' }\"\n            />\n            <c8y-messages\n              [show]=\"formGroup.controls.label.touched && formGroup.controls.label.errors\"\n            >\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['label'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div\n          class=\"col-md-6\"\n          *ngIf=\"formGroup.controls?.unit\"\n        >\n          <c8y-form-group class=\"form-group-sm\">\n            <label translate>Unit</label>\n            <input\n              class=\"form-control\"\n              name=\"unit\"\n              formControlName=\"unit\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: '\u00BAC' }\"\n            />\n            <c8y-messages\n              [show]=\"formGroup.controls.unit.touched && formGroup.controls.unit.errors\"\n            >\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['unit'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div\n          class=\"col-md-6\"\n          *ngIf=\"formGroup.controls?.target && showTarget\"\n        >\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error':\n                (range?.touched || formGroup.controls.target.touched) &&\n                formGroup.controls?.target?.errors\n            }\"\n          >\n            <label translate>Target</label>\n            <input\n              class=\"form-control\"\n              name=\"target\"\n              type=\"number\"\n              formControlName=\"target\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 25 }\"\n            />\n            <c8y-messages\n              [show]=\"\n                (range?.touched || formGroup.controls.target.touched) &&\n                formGroup.controls.target.errors\n              \"\n            >\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['target'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n    <fieldset\n      class=\"c8y-fieldset\"\n      *ngIf=\"range && showRange\"\n    >\n      <legend translate>Range</legend>\n      <div\n        class=\"row\"\n        formGroupName=\"range\"\n      >\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{ 'has-error': range?.touched && range?.controls?.min?.errors }\"\n          >\n            <label translate>Min</label>\n            <input\n              class=\"form-control\"\n              name=\"min\"\n              type=\"number\"\n              formControlName=\"min\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 0 }\"\n            />\n            <c8y-messages [show]=\"range?.touched && range.controls?.min?.errors\"></c8y-messages>\n          </c8y-form-group>\n        </div>\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{ 'has-error': range?.touched && range?.controls?.max?.errors }\"\n          >\n            <label translate>Max</label>\n            <input\n              class=\"form-control\"\n              name=\"max\"\n              type=\"number\"\n              formControlName=\"max\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 100 }\"\n            />\n            <c8y-messages [show]=\"range?.touched && range.controls?.max?.errors\">\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['max'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n\n    <fieldset\n      class=\"c8y-fieldset\"\n      formGroupName=\"yellowRange\"\n      *ngIf=\"yellowRange && showYellowRange\"\n    >\n      <legend translate>Yellow range</legend>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error':\n                (range?.touched || yellowRange?.touched) && yellowRange?.controls?.min?.errors\n            }\"\n          >\n            <label translate>Min</label>\n            <input\n              class=\"form-control\"\n              name=\"min\"\n              type=\"number\"\n              formControlName=\"min\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 50 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || yellowRange?.touched) && yellowRange.controls?.min?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error':\n                (range?.touched || yellowRange?.touched) && yellowRange?.controls?.max?.errors\n            }\"\n          >\n            <label translate>Max</label>\n            <input\n              class=\"form-control\"\n              name=\"max\"\n              type=\"number\"\n              formControlName=\"max\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 75 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || yellowRange?.touched) && yellowRange.controls?.max?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n\n    <fieldset\n      class=\"c8y-fieldset\"\n      formGroupName=\"redRange\"\n      *ngIf=\"redRange && showRedRange\"\n    >\n      <legend translate>Red range</legend>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error': (range?.touched || redRange?.touched) && redRange?.controls?.min?.errors\n            }\"\n          >\n            <label translate>Min</label>\n            <input\n              class=\"form-control\"\n              name=\"min\"\n              type=\"number\"\n              formControlName=\"min\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 75 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || redRange?.touched) && redRange.controls?.min?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error': (range?.touched || redRange?.touched) && redRange?.controls?.max?.errors\n            }\"\n          >\n            <label translate>Max</label>\n            <input\n              class=\"form-control\"\n              name=\"max\"\n              type=\"number\"\n              formControlName=\"max\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 100 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || redRange?.touched) && redRange.controls?.max?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n  </ng-container>\n\n  <fieldset\n    class=\"c8y-fieldset\"\n    *ngIf=\"showChartForm\"\n    formGroupName=\"chart\"\n  >\n    <legend translate>Chart</legend>\n    <div class=\"tight-grid\">\n      <div\n        class=\"col-xs-6 col-sm-4\"\n        *ngIf=\"selectableChartRenderTypes?.length !== 0\"\n      >\n        <c8y-form-group class=\"form-group-sm\">\n          <ng-container *ngTemplateOutlet=\"displayHelpButton\"></ng-container>\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"renderType\"\n            >\n              <option\n                *ngFor=\"let type of CHART_RENDER_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n          </div>\n        </c8y-form-group>\n      </div>\n      <div\n        class=\"col-xs-6 col-sm-4\"\n        *ngIf=\"selectableChartLineTypes?.length !== 0\"\n      >\n        <c8y-form-group class=\"form-group-sm\">\n          <label\n            for=\"chartType\"\n            translate\n          >\n            Chart type\n          </label>\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"lineType\"\n            >\n              <option\n                *ngFor=\"let type of CHART_LINE_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n            <span></span>\n          </div>\n        </c8y-form-group>\n      </div>\n      <div\n        class=\"col-xs-6 col-sm-4\"\n        *ngIf=\"selectableAxisTypes?.length !== 0\"\n      >\n        <c8y-form-group class=\"form-group-sm\">\n          <label\n            for=\"yAxis\"\n            translate\n          >\n            Y-axis\n          </label>\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"yAxisType\"\n            >\n              <option\n                *ngFor=\"let type of AXIS_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n            <span></span>\n          </div>\n        </c8y-form-group>\n      </div>\n    </div>\n  </fieldset>\n  <fieldset\n    class=\"c8y-fieldset\"\n    *ngIf=\"showOnlyDisplayForm\"\n    formGroupName=\"display\"\n  >\n    <legend>\n      <ng-container *ngTemplateOutlet=\"displayHelpButton\"></ng-container>\n    </legend>\n    <div class=\"tight-grid\">\n      <div class=\"col-xs-6 col-sm-4\">\n        <c8y-form-group class=\"form-group-sm\">\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"renderType\"\n            >\n              <option\n                *ngFor=\"let type of CHART_RENDER_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n          </div>\n        </c8y-form-group>\n      </div>\n    </div>\n  </fieldset>\n</div>\n\n<ng-template #displayHelpButton>\n  <label>\n    {{ 'Display' | translate }}\n    <button\n      class=\"btn-help btn-help--sm\"\n      [attr.aria-label]=\"'Help' | translate\"\n      popover=\"{{ 'Value displayed when data is aggregated' | translate }}\"\n      triggers=\"focus\"\n      type=\"button\"\n      placement=\"right\"\n    ></button>\n  </label>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i2.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { 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: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointAttributesFormComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoint-attributes-form', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => DatapointAttributesFormComponent),
                            multi: true
                        },
                        {
                            provide: NG_VALIDATORS,
                            useExisting: forwardRef(() => DatapointAttributesFormComponent),
                            multi: true
                        }
                    ], imports: [
                        FormsModule,
                        ReactiveFormsModule,
                        NgIf,
                        C8yTranslateDirective,
                        FormGroupComponent,
                        RequiredInputPlaceholderDirective,
                        MessagesComponent,
                        NgFor,
                        MessageDirective,
                        NgClass,
                        NgTemplateOutlet,
                        PopoverDirective,
                        C8yTranslatePipe,
                        KeyValuePipe
                    ], template: "<div [formGroup]=\"formGroup\">\n  <ng-container *ngIf=\"!rawValue?.__template || showFormIfTemplateWasSelected\">\n    <fieldset\n      class=\"c8y-fieldset\"\n      *ngIf=\"formGroup.controls?.label || formGroup.controls?.unit || formGroup.controls?.target\"\n    >\n      <legend translate>Details</legend>\n      <div class=\"row\">\n        <div\n          class=\"col-md-6\"\n          *ngIf=\"formGroup.controls?.label\"\n        >\n          <c8y-form-group class=\"form-group-sm\">\n            <label translate>Label</label>\n            <input\n              class=\"form-control\"\n              name=\"label\"\n              formControlName=\"label\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 'Temperature' }\"\n            />\n            <c8y-messages\n              [show]=\"formGroup.controls.label.touched && formGroup.controls.label.errors\"\n            >\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['label'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div\n          class=\"col-md-6\"\n          *ngIf=\"formGroup.controls?.unit\"\n        >\n          <c8y-form-group class=\"form-group-sm\">\n            <label translate>Unit</label>\n            <input\n              class=\"form-control\"\n              name=\"unit\"\n              formControlName=\"unit\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: '\u00BAC' }\"\n            />\n            <c8y-messages\n              [show]=\"formGroup.controls.unit.touched && formGroup.controls.unit.errors\"\n            >\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['unit'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div\n          class=\"col-md-6\"\n          *ngIf=\"formGroup.controls?.target && showTarget\"\n        >\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error':\n                (range?.touched || formGroup.controls.target.touched) &&\n                formGroup.controls?.target?.errors\n            }\"\n          >\n            <label translate>Target</label>\n            <input\n              class=\"form-control\"\n              name=\"target\"\n              type=\"number\"\n              formControlName=\"target\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 25 }\"\n            />\n            <c8y-messages\n              [show]=\"\n                (range?.touched || formGroup.controls.target.touched) &&\n                formGroup.controls.target.errors\n              \"\n            >\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['target'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n    <fieldset\n      class=\"c8y-fieldset\"\n      *ngIf=\"range && showRange\"\n    >\n      <legend translate>Range</legend>\n      <div\n        class=\"row\"\n        formGroupName=\"range\"\n      >\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{ 'has-error': range?.touched && range?.controls?.min?.errors }\"\n          >\n            <label translate>Min</label>\n            <input\n              class=\"form-control\"\n              name=\"min\"\n              type=\"number\"\n              formControlName=\"min\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 0 }\"\n            />\n            <c8y-messages [show]=\"range?.touched && range.controls?.min?.errors\"></c8y-messages>\n          </c8y-form-group>\n        </div>\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{ 'has-error': range?.touched && range?.controls?.max?.errors }\"\n          >\n            <label translate>Max</label>\n            <input\n              class=\"form-control\"\n              name=\"max\"\n              type=\"number\"\n              formControlName=\"max\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 100 }\"\n            />\n            <c8y-messages [show]=\"range?.touched && range.controls?.max?.errors\">\n              <c8y-message\n                *ngFor=\"let item of customValidationErrorMessages['max'] | keyvalue\"\n                [name]=\"item.key\"\n                [text]=\"item.value\"\n              ></c8y-message>\n            </c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n\n    <fieldset\n      class=\"c8y-fieldset\"\n      formGroupName=\"yellowRange\"\n      *ngIf=\"yellowRange && showYellowRange\"\n    >\n      <legend translate>Yellow range</legend>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error':\n                (range?.touched || yellowRange?.touched) && yellowRange?.controls?.min?.errors\n            }\"\n          >\n            <label translate>Min</label>\n            <input\n              class=\"form-control\"\n              name=\"min\"\n              type=\"number\"\n              formControlName=\"min\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 50 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || yellowRange?.touched) && yellowRange.controls?.min?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error':\n                (range?.touched || yellowRange?.touched) && yellowRange?.controls?.max?.errors\n            }\"\n          >\n            <label translate>Max</label>\n            <input\n              class=\"form-control\"\n              name=\"max\"\n              type=\"number\"\n              formControlName=\"max\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 75 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || yellowRange?.touched) && yellowRange.controls?.max?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n\n    <fieldset\n      class=\"c8y-fieldset\"\n      formGroupName=\"redRange\"\n      *ngIf=\"redRange && showRedRange\"\n    >\n      <legend translate>Red range</legend>\n      <div class=\"row\">\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error': (range?.touched || redRange?.touched) && redRange?.controls?.min?.errors\n            }\"\n          >\n            <label translate>Min</label>\n            <input\n              class=\"form-control\"\n              name=\"min\"\n              type=\"number\"\n              formControlName=\"min\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 75 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || redRange?.touched) && redRange.controls?.min?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n\n        <div class=\"col-md-6\">\n          <c8y-form-group class=\"form-group-sm\"\n            [ngClass]=\"{\n              'has-error': (range?.touched || redRange?.touched) && redRange?.controls?.max?.errors\n            }\"\n          >\n            <label translate>Max</label>\n            <input\n              class=\"form-control\"\n              name=\"max\"\n              type=\"number\"\n              formControlName=\"max\"\n              [placeholder]=\"'e.g. {{ example }}' | translate: { example: 100 }\"\n            />\n            <c8y-messages\n              [show]=\"(range?.touched || redRange?.touched) && redRange.controls?.max?.errors\"\n            ></c8y-messages>\n          </c8y-form-group>\n        </div>\n      </div>\n    </fieldset>\n  </ng-container>\n\n  <fieldset\n    class=\"c8y-fieldset\"\n    *ngIf=\"showChartForm\"\n    formGroupName=\"chart\"\n  >\n    <legend translate>Chart</legend>\n    <div class=\"tight-grid\">\n      <div\n        class=\"col-xs-6 col-sm-4\"\n        *ngIf=\"selectableChartRenderTypes?.length !== 0\"\n      >\n        <c8y-form-group class=\"form-group-sm\">\n          <ng-container *ngTemplateOutlet=\"displayHelpButton\"></ng-container>\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"renderType\"\n            >\n              <option\n                *ngFor=\"let type of CHART_RENDER_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n          </div>\n        </c8y-form-group>\n      </div>\n      <div\n        class=\"col-xs-6 col-sm-4\"\n        *ngIf=\"selectableChartLineTypes?.length !== 0\"\n      >\n        <c8y-form-group class=\"form-group-sm\">\n          <label\n            for=\"chartType\"\n            translate\n          >\n            Chart type\n          </label>\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"lineType\"\n            >\n              <option\n                *ngFor=\"let type of CHART_LINE_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n            <span></span>\n          </div>\n        </c8y-form-group>\n      </div>\n      <div\n        class=\"col-xs-6 col-sm-4\"\n        *ngIf=\"selectableAxisTypes?.length !== 0\"\n      >\n        <c8y-form-group class=\"form-group-sm\">\n          <label\n            for=\"yAxis\"\n            translate\n          >\n            Y-axis\n          </label>\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"yAxisType\"\n            >\n              <option\n                *ngFor=\"let type of AXIS_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n            <span></span>\n          </div>\n        </c8y-form-group>\n      </div>\n    </div>\n  </fieldset>\n  <fieldset\n    class=\"c8y-fieldset\"\n    *ngIf=\"showOnlyDisplayForm\"\n    formGroupName=\"display\"\n  >\n    <legend>\n      <ng-container *ngTemplateOutlet=\"displayHelpButton\"></ng-container>\n    </legend>\n    <div class=\"tight-grid\">\n      <div class=\"col-xs-6 col-sm-4\">\n        <c8y-form-group class=\"form-group-sm\">\n          <div class=\"c8y-select-wrapper\">\n            <select\n              class=\"form-control\"\n              formControlName=\"renderType\"\n            >\n              <option\n                *ngFor=\"let type of CHART_RENDER_TYPES\"\n                [ngValue]=\"type.val\"\n              >\n                {{ type.text | translate }}\n              </option>\n            </select>\n          </div>\n        </c8y-form-group>\n      </div>\n    </div>\n  </fieldset>\n</div>\n\n<ng-template #displayHelpButton>\n  <label>\n    {{ 'Display' | translate }}\n    <button\n      class=\"btn-help btn-help--sm\"\n      [attr.aria-label]=\"'Help' | translate\"\n      popover=\"{{ 'Value displayed when data is aggregated' | translate }}\"\n      triggers=\"focus\"\n      type=\"button\"\n      placement=\"right\"\n    ></button>\n  </label>\n</ng-template>\n" }]
        }], ctorParameters: () => [{ type: DatapointAttributesFormValidationService }], propDecorators: { selectableChartRenderTypes: [{
                type: Input
            }], selectableChartLineTypes: [{
                type: Input
            }], selectableAxisTypes: [{
                type: Input
            }], showTarget: [{
                type: Input
            }], showRange: [{
                type: Input
            }], showYellowRange: [{
                type: Input
            }], showRedRange: [{
                type: Input
            }], showChart: [{
                type: Input
            }], showFormIfTemplateWasSelected: [{
                type: Input
            }] } });

const DATAPOINT_LIBRARY_FRAGMENT = 'c8y_Kpi';

class DatapointLibraryService {
    constructor(inventory, appState, measurements, color) {
        this.inventory = inventory;
        this.appState = appState;
        this.measurements = measurements;
        this.color = color;
        this.appState.currentUser.pipe(filter(user => !user)).subscribe(() => {
            this.cache = undefined;
        });
    }
    async getAllDatapointLibraryEntriesCached(forceCacheRenew = false) {
        if (forceCacheRenew) {
            this.cache = undefined;
        }
        if (!this.cache) {
            this.cache = this.getAllDatapointLibraryEntries();
        }
        return this.cache;
    }
    async getFirstDatapointLibraryPage() {
        const filterObj = {
            currentPage: 1,
            pageSize: 50,
            fragmentType: DATAPOINT_LIBRARY_FRAGMENT,
            withTotalPages: true
        };
        return (await this.inventory.list(filterObj));
    }
    async getAllDatapointLibraryItemsCached() {
        if (!this.cache) {
            this.cache = this.getAllDatapointLibraryEntries();
        }
        const res = await this.cache;
        return res.map(tmp => tmp[DATAPOINT_LIBRARY_FRAGMENT]);
    }
    async updateDatapoints(datapoints, skipUpdatingTarget = false) {
        if (!Array.isArray(datapoints)) {
            return datapoints;
        }
        const currentTargetsPromise = !skipUpdatingTarget
            ? this.getCurrentVersionOfTargetsFromDatapoints(datapoints)
            : Promise.resolve([]);
        const [currentTemplates, currentTargets] = await Promise.all([
            this.getCurrentTemplatesFromDatapoints(datapoints),
            currentTargetsPromise
        ]);
        const currentTemplateVersions = currentTemplates
            .map(tmp => this.mapDatapointLibraryEntry(tmp))
            .filter(tmp => !!tmp);
        for (const datapoint of datapoints) {
            const { fragment, series, __active, __target, color, label, __template } = datapoint;
            const foundCurrentTemplateVersion = currentTemplateVersions.find(tmp => tmp.__template === datapoint.__template);
            if (foundCurrentTemplateVersion) {
                Object.assign(datapoint, foundCurrentTemplateVersion);
                Object.assign(datapoint, {
                    fragment,
                    series,
                    __active,
                    __target,
                    color,
                    label,
                    __template
                });
            }
            const foundCurrentTarget = currentTargets.find(target => target.id === __target?.id);
            if (foundCurrentTarget) {
                const { id, name } = foundCurrentTarget;
                datapoint.__target = { id, name };
            }
        }
        return datapoints;
    }
    async getDatapointsOfAsset(parentReference, ignoreDatapointTemplates, datapointTemplatesOnly = false) {
        const [kpiResponse, details] = await Promise.all([
            (ignoreDatapointTemplates
                ? Promise.resolve(null)
                : this.inventory.assetKPIsList(parentReference, { pageSize: MAX_PAGE_SIZE })),
            this.inventory.getMeasurementsAndSeries(parentReference)
        ]);
        const kpis = kpiResponse && kpiResponse.data ? kpiResponse.data : [];
        const sortedDetails = sortBy(details, ['fragment', 'series']);
        return await this.combineFragmentSeriesTuplesWithDetails(sortedDetails, parentReference, kpis, datapointTemplatesOnly);
    }
    /**
     * Requests the last measurement with the given fragment and series to extract it's unit.
     * If the source attribute is provided, it will check the last measurement for this specific source.
     * @returns found unit or an empty string instead
     */
    async guessUnitOfDatapoint(fragment, series, source) {
        const measurementfilter = {
            valueFragmentSeries: series,
            valueFragmentType: fragment,
            pageSize: 1,
            revert: true,
            dateFrom: '1970-01-01'
        };
        if (source?.id) {
            measurementfilter.source = source?.id;
        }
        try {
            const { data: lastMeasurements } = await this.measurements.list(measurementfilter);
            const measurement = lastMeasurements[0];
            if (measurement) {
                const pathToUnit = `${fragment}.${series}.unit`;
                const unit = get(measurement, pathToUnit);
                if (unit?.length && typeof unit === 'string') {
                    return unit;
                }
            }
        }
        catch {
            // nothing to do
        }
        return '';
    }
    async combineFragmentSeriesTuplesWithDetails(tuples, target, kpis, datapointTemplatesOnly = false) {
        const datapoints = tuples
            .map(tuple => {
            const foundDatapointLibraryEntry = kpis.find(kpi => kpi[DATAPOINT_LIBRARY_FRAGMENT] &&
                kpi[DATAPOINT_LIBRARY_FRAGMENT].fragment === tuple.fragment &&
                kpi[DATAPOINT_LIBRARY_FRAGMENT].series === tuple.series);
            if (!foundDatapointLibraryEntry && datapointTemplatesOnly) {
                return null;
            }
            const datapoint = this.mapDatapointLibraryEntry(foundDatapointLibraryEntry) || tuple;
            if (!datapoint.label) {
                datapoint.label = `${datapoint.fragment} → ${datapoint.series}`;
            }
            if (!datapoint.unit?.length) {
                datapoint.unit = '';
            }
            datapoint.__target = target;
            return datapoint;
        })
            .filter(Boolean);
        await this.assignColorToDatapoints(datapoints);
        return datapoints;
    }
    async assignColorToDatapoints(datapoints) {
        const datapointsWithoutColor = datapoints.filter(datapoint => !datapoint.color);
        await Promise.all(datapointsWithoutColor.map(datapoint => this.color
            .generateColorForDatapoint(datapoint.fragment, datapoint.series)
            .then(color => (datapoint.color = color))));
    }
    async getAllDatapointLibraryEntries() {
        const entries = new Array();
        const filterObj = {
            currentPage: 1,
            pageSize: MAX_PAGE_SIZE,
            fragmentType: DATAPOINT_LIBRARY_FRAGMENT
        };
        let res = await this.inventory.list(filterObj);
        while (res.data.length) {
            entries.push(...res.data);
            if (res.data.length < res.paging.pageSize) {
                break;
            }
            if (!res.paging.nextPage) {
                break;
            }
            res = await res.paging.next();
        }
        return entries;
    }
    mapDatapointLibraryEntry(entry) {
        if (!entry || !entry[DATAPOINT_LIBRARY_FRAGMENT]) {
            return null;
        }
        const datapoint = entry[DATAPOINT_LIBRARY_FRAGMENT];
        datapoint.__template = entry.id;
        return datapoint;
    }
    async getCurrentTemplatesFromDatapoints(datapoints) {
        const datapointsWithTemplateId = datapoints.filter(dp => !!dp.__template);
        const usedTemplateIds = datapointsWithTemplateId.map(dp => dp.__template);
        return await this.getMOsByIds(usedTemplateIds);
    }
    async getCurrentVersionOfTargetsFromDatapoints(datapoints) {
        const datapointsWithTarget = datapoints.filter(dp => !!dp.__target?.id);
        const usedTargetIds = datapointsWithTarget.map(dp => dp.__target.id);
        return await this.getMOsByIds(usedTargetIds);
    }
    async getMOsByIds(ids) {
        const uniqManagedObjectIds = uniq(ids);
        if (!uniqManagedObjectIds.length) {
            return [];
        }
        try {
            const { data: managedObjects } = await this.inventory.list({
                ids: uniqManagedObjectIds.join(),
                pageSize: MAX_PAGE_SIZE
            });
            return managedObjects;
        }
        catch {
            // Fail silently in case we are not able to talk to the inventory API.
            // Should only be reached in case of an server side error.
            // instead of failing, pretend like we didn't receive any items.
            console.warn(`Failed to get the current version of the following managedObjects: ${uniqManagedObjectIds.join()}.`);
            return [];
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointLibraryService, deps: [{ token: i1.InventoryService }, { token: i2$1.AppStateService }, { token: i1.MeasurementService }, { token: i2$1.ColorService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointLibraryService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointLibraryService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: i1.InventoryService }, { type: i2$1.AppStateService }, { type: i1.MeasurementService }, { type: i2$1.ColorService }] });

class DatapointTemplatePopoverComponent {
    constructor() {
        this.attributes = [
            {
                label: gettext('Fragment'),
                key: 'fragment'
            },
            {
                label: gettext('Series'),
                key: 'series'
            },
            {
                label: gettext('Unit'),
                key: 'unit'
            },
            {
                label: gettext('Range'),
                key: 'min'
            },
            {
                label: gettext('Target'),
                key: 'target'
            },
            {
                label: gettext('Yellow range'),
                labelColor: 'yellow',
                key: 'yellowRangeMin'
            },
            {
                label: gettext('Red range'),
                labelColor: 'red',
                key: 'redRangeMin'
            }
        ];
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointTemplatePopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DatapointTemplatePopoverComponent, isStandalone: true, selector: "c8y-datapoint-template-popover", inputs: { datapoint: "datapoint", attributes: "attributes" }, ngImport: i0, template: "<p class=\"text-medium\">\n  <i c8yIcon=\"circle\" [style.color]=\"datapoint.color\"></i>\n  {{ datapoint.label }}\n</p>\n<p>{{ datapoint.description }}</p>\n\n<ul class=\"list-unstyled small p-t-16\">\n  <ng-container *ngFor=\"let attribute of attributes; let i = index\">\n    <li\n      class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\"\n      *ngIf=\"datapoint[attribute.key] !== undefined\"\n    >\n      <label class=\"small m-b-0 m-r-8\">\n        <i *ngIf=\"attribute.labelColor\" c8yIcon=\"square\" [style.color]=\"attribute.labelColor\"></i>\n        {{ attribute.label | translate }}\n      </label>\n      <ng-container [ngSwitch]=\"attribute.key\">\n        <span *ngSwitchCase=\"'min'\" class=\"m-l-auto\">\n          {{ datapoint['min'] }} \u2014 {{ datapoint['max'] }}\n        </span>\n        <span *ngSwitchCase=\"'yellowRangeMin'\" class=\"m-l-auto\">\n          {{ datapoint['yellowRangeMin'] }} \u2014 {{ datapoint['yellowRangeMax'] }}\n        </span>\n        <span *ngSwitchCase=\"'redRangeMin'\" class=\"m-l-auto\">\n          {{ datapoint['redRangeMin'] }} \u2014 {{ datapoint['redRangeMax'] }}\n        </span>\n        <span *ngSwitchDefault class=\"m-l-auto\">\n          {{ datapoint[attribute.key] }}\n        </span>\n      </ng-container>\n    </li>\n  </ng-container>\n</ul>\n", dependencies: [{ kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { kind: "directive", type: NgSwitchDefault, selector: "[ngSwitchDefault]" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointTemplatePopoverComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoint-template-popover', imports: [IconDirective, NgFor, NgIf, NgSwitch, NgSwitchCase, NgSwitchDefault, C8yTranslatePipe], template: "<p class=\"text-medium\">\n  <i c8yIcon=\"circle\" [style.color]=\"datapoint.color\"></i>\n  {{ datapoint.label }}\n</p>\n<p>{{ datapoint.description }}</p>\n\n<ul class=\"list-unstyled small p-t-16\">\n  <ng-container *ngFor=\"let attribute of attributes; let i = index\">\n    <li\n      class=\"p-t-4 p-b-4 d-flex separator-bottom text-nowrap\"\n      *ngIf=\"datapoint[attribute.key] !== undefined\"\n    >\n      <label class=\"small m-b-0 m-r-8\">\n        <i *ngIf=\"attribute.labelColor\" c8yIcon=\"square\" [style.color]=\"attribute.labelColor\"></i>\n        {{ attribute.label | translate }}\n      </label>\n      <ng-container [ngSwitch]=\"attribute.key\">\n        <span *ngSwitchCase=\"'min'\" class=\"m-l-auto\">\n          {{ datapoint['min'] }} \u2014 {{ datapoint['max'] }}\n        </span>\n        <span *ngSwitchCase=\"'yellowRangeMin'\" class=\"m-l-auto\">\n          {{ datapoint['yellowRangeMin'] }} \u2014 {{ datapoint['yellowRangeMax'] }}\n        </span>\n        <span *ngSwitchCase=\"'redRangeMin'\" class=\"m-l-auto\">\n          {{ datapoint['redRangeMin'] }} \u2014 {{ datapoint['redRangeMax'] }}\n        </span>\n        <span *ngSwitchDefault class=\"m-l-auto\">\n          {{ datapoint[attribute.key] }}\n        </span>\n      </ng-container>\n    </li>\n  </ng-container>\n</ul>\n" }]
        }], propDecorators: { datapoint: [{
                type: Input
            }], attributes: [{
                type: Input
            }] } });

const AddButtonTypes = {
    none: 'none',
    addRemove: 'add-remove',
    select: 'select'
};
class DatapointSelectorListItemComponent {
    constructor(formBuilder) {
        this.formBuilder = formBuilder;
        this.defaultFormOptions = {};
        this.isSelected = false;
        this.isCollapsed = true;
        this.addButtonType = AddButtonTypes.addRemove;
        this.editable = true;
        this.showActiveToggle = false;
        this.activeToggleDisabled = false;
        this.showOptions = false;
        this.actions = [];
        this.optionToRemove = false;
        this.hasUnlinkTemplateOption = false;
        this.added = new EventEmitter();
        this.removed = new EventEmitter();
        this.colorPickerDisabled = true;
        this.disableTypeaheadIfSelected = false;
        this.pattern = '';
        this.AddButtonTypes = AddButtonTypes;
        this.formGroup = this.formBuilder.group({
            details: [],
            color: [],
            __active: [],
            __target: [],
            fragment: [],
            series: [],
            __template: []
        });
        this.isValid$ = this.formGroup.statusChanges.pipe(map(status => status === 'VALID'), startWith(this.formGroup.valid));
    }
    validate(_control) {
        if (this.formGroup?.invalid) {
            Object.keys(this.formGroup.controls).forEach(controlName => {
                const control = this.formGroup.controls[controlName];
                if (control.invalid) {
                    const errors = control.errors;
                    if (errors) {
                        this.errorMessage = Object.values(errors)[0].message;
                    }
                }
            });
        }
        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))).subscribe(fn);
    }
    registerOnTouched(fn) {
        this.formGroup.valueChanges.pipe(take(1)).subscribe(fn);
    }
    setDisabledState(isDisabled) {
        if (this.formGroup?.disabled === isDisabled) {
            return;
        }
        isDisabled ? this.formGroup.disable() : this.formGroup.enable();
    }
    collapse() {
        this.isCollapsed = !this.isCollapsed;
    }
    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));
    }
    setPipe(filterStr) {
        this.pattern = filterStr;
        this.filterPipe = pipe(map((data) => {
            return this.filterDatapointLabel(data, filterStr);
        }));
    }
    unlinkDatapointTemplate() {
        const details = this.formGroup.value.details || {};
        this.resetUnusedProperties(details);
        this.formGroup.patchValue({ __template: undefined, details });
    }
    dataPointTemplateSelected(template) {
        const attributesToAssign = [
            'color',
            'label',
            'min',
            'max',
            'yellowRangeMax',
            'yellowRangeMin',
            'redRangeMax',
            'redRangeMin',
            'target',
            'orientation',
            'unit'
        ];
        const { fragment, series, __target, __active } = this.formGroup.value;
        const dataPoint = {
            fragment,
            series,
            __active,
            __target,
            __template: template.id
        };
        for (const attribute of attributesToAssign) {
            const value = template[DATAPOINT_LIBRARY_FRAGMENT][attribute];
            dataPoint[attribute] = value;
        }
        this.writeValue(dataPoint);
        this.setPipe('');
    }
    resetUnusedProperties(details) {
        const { showTarget, showYellowRange, showRedRange } = this.defaultFormOptions;
        details.__template = undefined;
        if (!showTarget) {
            details.target = undefined;
        }
        if (!showYellowRange) {
            details.yellowRangeMin = undefined;
            details.yellowRangeMax = undefined;
        }
        if (!showRedRange) {
            details.redRangeMin = undefined;
            details.redRangeMax = undefined;
        }
    }
    filterDatapointLabel(kpis, filterStr) {
        return kpis.filter((mo) => mo[DATAPOINT_LIBRARY_FRAGMENT] &&
            mo[DATAPOINT_LIBRARY_FRAGMENT].label &&
            typeof mo[DATAPOINT_LIBRARY_FRAGMENT].label === 'string' &&
            mo[DATAPOINT_LIBRARY_FRAGMENT].label.toLowerCase().indexOf(filterStr.toLowerCase()) > -1);
    }
    transformFormValue(formValue) {
        const obj = Object.assign({}, formValue.details || {}, formValue);
        delete obj.details;
        return obj;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorListItemComponent, deps: [{ token: i2.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DatapointSelectorListItemComponent, isStandalone: true, selector: "c8y-datapoint-selector-list-item", inputs: { defaultFormOptions: "defaultFormOptions", isSelected: "isSelected", isCollapsed: "isCollapsed", addButtonType: "addButtonType", editable: "editable", showActiveToggle: "showActiveToggle", activeToggleDisabled: "activeToggleDisabled", showOptions: "showOptions", datapointLibraryEntries: "datapointLibraryEntries", actions: "actions", optionToRemove: "optionToRemove", hasUnlinkTemplateOption: "hasUnlinkTemplateOption", colorPickerDisabled: "colorPickerDisabled", disableTypeaheadIfSelected: "disableTypeaheadIfSelected", highlightText: "highlightText" }, outputs: { added: "added", removed: "removed" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => DatapointSelectorListItemComponent),
                multi: true
            },
            {
                provide: NG_VALIDATORS,
                useExisting: forwardRef(() => DatapointSelectorListItemComponent),
                multi: true
            }
        ], queries: [{ propertyName: "dragHandle", first: true, predicate: ListItemDragHandleComponent, descendants: true }], ngImport: i0, template: "<c8y-li class=\"c8y-list__item__collapse--container-small\" [formGroup]=\"formGroup\" #li>\n  <c8y-li-drag-handle><ng-content select=\"c8y-li-drag-handle\"></ng-content></c8y-li-drag-handle>\n  <c8y-li-checkbox\n    class=\"a-s-center p-r-0\"\n    *ngIf=\"showActiveToggle\"\n    [displayAsSwitch]=\"true\"\n    formControlName=\"__active\"\n    (click)=\"$event.stopPropagation()\"\n  ></c8y-li-checkbox>\n\n  <div class=\"d-flex a-i-center \">\n    <div class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-16\" [title]=\"'Change color' | translate\">\n      <div class=\"c8y-colorpicker\">\n        <input\n          type=\"color\"\n          [attr.aria-label]=\"'Color' | translate\"\n          formControlName=\"color\"\n          (click)=\"$event.stopPropagation()\"\n        />\n        <span [style.background-color]=\"formGroup.value.color\"></span>\n      </div>\n    </div>\n    <button\n      class=\"btn-clean data-point-label text-truncate\"\n      type=\"button\"\n      [attr.aria-expanded]=\"!li.collapsed\"\n      (click)=\"li.collapsed = !li.collapsed\"\n    >\n      <span class=\"text-truncate\" [title]=\"formGroup.value.details?.label\">\n        <c8y-highlight\n          [text]=\"formGroup.value.details?.label\"\n          [pattern]=\"highlightText\"\n          [shouldTrimPattern]=\"true\"\n        ></c8y-highlight>\n      </span>\n      <small class=\"text-truncate text-muted icon-flex\" *ngIf=\"formGroup.value.__target\">\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 btn-dot btn-dot--danger m-l-auto\"\n      type=\"button\"\n      [attr.aria-label]=\"'Invalid' | translate\"\n      [popover]=\"\n        errorMessage\n          ? errorMessage\n          : ('Some entries are invalid. Check the input fields with red borders.' | translate)\n      \"\n      triggers=\"focus\"\n      placement=\"left\"\n      container=\"body\"\n      *ngIf=\"!(isValid$ | async)\"\n    >\n      <i c8yIcon=\"warning\"></i>\n    </button>\n    <div class=\"m-l-auto a-s-center p-r-4\" *ngIf=\"addButtonType === AddButtonTypes.addRemove\">\n      <button\n        class=\"btn btn-dot btn-dot--danger\"\n        type=\"button\"\n        [attr.aria-label]=\"'Remove' | translate\"\n        [tooltip]=\"'Remove from selected data points' | translate\"\n        [delay]=\"500\"\n        (click)=\"addOrRemoveItem()\"\n        *ngIf=\"isSelected\"\n        [attr.data-cy]=\"'datapoint-selector-list-item--remove-datapoint-button'\"\n      >\n        <i class=\"icon-20\" c8yIcon=\"minus-circle\"></i>\n      </button>\n      <button\n        class=\"btn btn-dot text-primary\"\n        type=\"button\"\n        [attr.aria-label]=\"'Add to selected data points' | translate\"\n        [tooltip]=\"'Add to selected data points' | translate\"\n        [delay]=\"500\"\n        [disabled]=\"!(isValid$ | async)\"\n        (click)=\"addOrRemoveItem()\"\n        *ngIf=\"!isSelected\"\n        [attr.data-cy]=\"'datapoint-selector-list-item--add-datapoint-button'\"\n      >\n        <i class=\"text-primary icon-20\" c8yIcon=\"plus-circle\"></i>\n      </button>\n    </div>\n    <button\n        *ngIf=\"addButtonType === AddButtonTypes.select\"\n        class=\"btn btn-default btn-sm m-l-auto\"\n        type=\"button\"\n        [attr.aria-label]=\"'Select' | translate\"\n        [tooltip]=\"'Select data point' | translate\"\n        [delay]=\"500\"\n        (click)=\"addOrRemoveItem()\"\n      >{{ 'Select' | translate }}</button>\n  </div>\n\n  <c8y-li-action\n    *ngIf=\"optionToRemove\"\n    [icon]=\"'minus-circle'\"\n    [label]=\"'Remove from list' | translate\"\n    (click)=\"remove()\"\n  ></c8y-li-action>\n  <c8y-li-action\n    *ngFor=\"let action of actions\"\n    [icon]=\"action.icon\"\n    [label]=\"action.label\"\n    (click)=\"action.callback(formGroup.value)\"\n  ></c8y-li-action>\n  <c8y-li-collapse *ngIf=\"editable\">\n    <div class=\"data-point-details\">\n      <ul class=\"list-unstyled small m-b-16\">\n        <li class=\"p-t-4 p-b-4 d-flex separator-top-bottom\">\n          <label class=\"small m-b-0 m-r-8 a-s-start text-muted\" translate>Fragment</label>\n          <span class=\"m-l-auto\">\n            <c8y-highlight\n              [text]=\"formGroup.value.fragment\"\n              [pattern]=\"highlightText\"\n              [shouldTrimPattern]=\"true\"\n            ></c8y-highlight>\n          </span>\n        </li>\n        <li class=\"p-t-4 p-b-4 d-flex separator-bottom\">\n          <label class=\"small m-b-0 m-r-8 a-s-start text-muted\" translate>Series</label>\n          <span class=\"m-l-auto\">\n            <c8y-highlight\n              [text]=\"formGroup.value.series\"\n              [pattern]=\"highlightText\"\n              [shouldTrimPattern]=\"true\"\n            ></c8y-highlight>\n          </span>\n        </li>\n      </ul>\n      <div\n        class=\"form-group form-group-sm\"\n        *ngIf=\"datapointLibraryEntries && datapointLibraryEntries | async as libraryEntries\"\n      >\n        <label>\n          {{ 'Data point template' | translate }} \n          <button\n            class=\"btn-help btn-help--sm\"\n            type=\"button\"\n            [attr.aria-label]=\"'Help' | translate\"\n            [popover]=\"datapointHintPopoverTemplate\"\n            (click)=\"$event.stopPropagation()\"\n            triggers=\"focus\"\n            placement=\"top\"\n          ></button>\n        </label>\n      \n\n        <ng-template #datapointHintPopoverTemplate>\n          {{\n            'Using a data point template sets color, label, unit and ranges. Removing the template allows you to set the values manually.'\n              | translate\n          }}\n        </ng-template>\n        <div class=\"input-group input-group-sm\">\n          <c8y-typeahead\n            class=\"flex-grow\"\n            [placeholder]=\"'No template' | translate\"\n            [ngModel]=\"formGroup.value.__template ? formGroup.value.details : undefined\"\n            [ngModelOptions]=\"{ standalone: true }\"\n            (onSearch)=\"setPipe($event)\"\n            [displayProperty]=\"'label'\"\n            [hideNew]=\"true\"\n            *ngIf=\"datapointLibraryEntries\"\n            [disabled]=\"isSelected && disableTypeaheadIfSelected\"\n          >\n            <c8y-li\n              class=\"p-l-8 p-r-8 c8y-list__item--link interact\"\n              *c8yFor=\"\n                let item of datapointLibraryEntries;\n                loadMore: 'auto';\n                pipe: filterPipe;\n                notFound: notFoundTemplate\n              \"\n              (click)=\"dataPointTemplateSelected(item)\"\n              [active]=\"formGroup.value.__template === item.id\"\n              [attr.role]=\"'menuitem'\"\n            >\n              <c8y-highlight [text]=\"item.c8y_Kpi?.label\" [pattern]=\"pattern\"></c8y-highlight>\n              <c8y-li-icon icon=\"circle\" [style.color]=\"item.c8y_Kpi?.color\"></c8y-li-icon>\n            </c8y-li>\n            <ng-template #notFoundTemplate>\n              <c8y-li class=\"bg-level-2 p-8\" *ngIf=\"pattern.length > 0\">\n                <span>No match found.</span>\n              </c8y-li>\n            </ng-template>\n          </c8y-typeahead>\n          <div class=\"input-group-btn\">\n            <button\n              class=\"btn btn-default\"\n              type=\"button\"\n              [attr.aria-label]=\"'Info' | translate\"\n              [popover]=\"datapointOverviewPopoverTemplate\"\n              placement=\"left\"\n              triggers=\"focus\"\n              container=\"body\"\n              *ngIf=\"formGroup.value.__template\"\n            >\n              <i class=\"text-info\" c8yIcon=\"info\"></i>\n            </button>\n          </div>\n          <div class=\"input-group-btn\">\n            <button\n              class=\"btn btn-default\"\n              type=\"button\"\n              tooltip=\"{{ 'Unlink data point template' | translate }}\"\n              [attr.aria-label]=\"'Unlink data point template' | translate\"\n              [delay]=\"500\"\n              placement=\"left\"\n              container=\"body\"\n              [adaptivePosition]=\"false\"\n              *ngIf=\"formGroup.value.__template && hasUnlinkTemplateOption\"\n              (click)=\"unlinkDatapointTemplate()\"\n            >\n              <i c8yIcon=\"unlink\"></i>\n            </button>\n          </div>\n        </div>\n      </div>\n      <ng-template #datapointOverviewPopoverTemplate>\n        <c8y-datapoint-template-popover\n          [datapoint]=\"formGroup.value.details\"\n        ></c8y-datapoint-template-popover>\n      </ng-template>\n      <c8y-datapoint-attributes-form\n        *ngIf=\"defaultFormOptions\"\n        [showTarget]=\"defaultFormOptions.showTarget\"\n        [showRange]=\"defaultFormOptions.showRange\"\n        [showYellowRange]=\"defaultFormOptions.showYellowRange\"\n        [showRedRange]=\"defaultFormOptions.showRedRange\"\n        [showChart]=\"defaultFormOptions.showChart\"\n        [showFormIfTemplateWasSelected]=\"defaultFormOptions.showFormIfTemplateWasSelected\"\n        [selectableChartRenderTypes]=\"defaultFormOptions.selectableChartRenderTypes\"\n        [selectableChartLineTypes]=\"defaultFormOptions.selectableChartLineTypes\"\n        [selectableAxisTypes]=\"defaultFormOptions.selectableAxisTypes\"\n        formControlName=\"details\"\n      ></c8y-datapoint-attributes-form>\n    </div>\n  </c8y-li-collapse>\n</c8y-li>\n", dependencies: [{ kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListItemCheckboxComponent, selector: "c8y-list-item-checkbox, c8y-li-checkbox", inputs: ["selected", "indeterminate", "disabled", "displayAsSwitch"], outputs: ["onSelect"] }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "component", type: HighlightComponent, selector: "c8y-highlight", inputs: ["pattern", "text", "elementClass", "shouldTrimPattern"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { 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: 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: ListItemActionComponent, selector: "c8y-list-item-action, c8y-li-action", inputs: ["label", "icon", "disabled"], outputs: ["click"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ListItemCollapseComponent, selector: "c8y-list-item-collapse, c8y-li-collapse", inputs: ["collapseWay"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: TypeaheadComponent, selector: "c8y-typeahead", inputs: ["required", "maxlength", "disabled", "allowFreeEntries", "placeholder", "displayProperty", "icon", "name", "autoClose", "hideNew", "container", "selected", "highlightFirstItem"], outputs: ["onSearch", "onIconClick"] }, { 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: ListItemIconComponent, selector: "c8y-list-item-icon, c8y-li-icon", inputs: ["icon", "status"] }, { kind: "component", type: DatapointTemplatePopoverComponent, selector: "c8y-datapoint-template-popover", inputs: ["datapoint", "attributes"] }, { kind: "component", type: DatapointAttributesFormComponent, selector: "c8y-datapoint-attributes-form", inputs: ["selectableChartRenderTypes", "selectableChartLineTypes", "selectableAxisTypes", "showTarget", "showRange", "showYellowRange", "showRedRange", "showChart", "showFormIfTemplateWasSelected"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorListItemComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoint-selector-list-item', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => DatapointSelectorListItemComponent),
                            multi: true
                        },
                        {
                            provide: NG_VALIDATORS,
                            useExisting: forwardRef(() => DatapointSelectorListItemComponent),
                            multi: true
                        }
                    ], imports: [
                        ListItemComponent,
                        FormsModule,
                        ReactiveFormsModule,
                        ListItemDragHandleComponent,
                        NgIf,
                        ListItemCheckboxComponent,
                        RequiredInputPlaceholderDirective,
                        HighlightComponent,
                        IconDirective,
                        PopoverDirective,
                        TooltipDirective,
                        ListItemActionComponent,
                        NgFor,
                        ListItemCollapseComponent,
                        C8yTranslateDirective,
                        TypeaheadComponent,
                        ForOfDirective,
                        ListItemIconComponent,
                        DatapointTemplatePopoverComponent,
                        DatapointAttributesFormComponent,
                        C8yTranslatePipe,
                        AsyncPipe
                    ], template: "<c8y-li class=\"c8y-list__item__collapse--container-small\" [formGroup]=\"formGroup\" #li>\n  <c8y-li-drag-handle><ng-content select=\"c8y-li-drag-handle\"></ng-content></c8y-li-drag-handle>\n  <c8y-li-checkbox\n    class=\"a-s-center p-r-0\"\n    *ngIf=\"showActiveToggle\"\n    [displayAsSwitch]=\"true\"\n    formControlName=\"__active\"\n    (click)=\"$event.stopPropagation()\"\n  ></c8y-li-checkbox>\n\n  <div class=\"d-flex a-i-center \">\n    <div class=\"c8y-list__item__colorpicker p-t-0 p-b-0 p-l-16\" [title]=\"'Change color' | translate\">\n      <div class=\"c8y-colorpicker\">\n        <input\n          type=\"color\"\n          [attr.aria-label]=\"'Color' | translate\"\n          formControlName=\"color\"\n          (click)=\"$event.stopPropagation()\"\n        />\n        <span [style.background-color]=\"formGroup.value.color\"></span>\n      </div>\n    </div>\n    <button\n      class=\"btn-clean data-point-label text-truncate\"\n      type=\"button\"\n      [attr.aria-expanded]=\"!li.collapsed\"\n      (click)=\"li.collapsed = !li.collapsed\"\n    >\n      <span class=\"text-truncate\" [title]=\"formGroup.value.details?.label\">\n        <c8y-highlight\n          [text]=\"formGroup.value.details?.label\"\n          [pattern]=\"highlightText\"\n          [shouldTrimPattern]=\"true\"\n        ></c8y-highlight>\n      </span>\n      <small class=\"text-truncate text-muted icon-flex\" *ngIf=\"formGroup.value.__target\">\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 btn-dot btn-dot--danger m-l-auto\"\n      type=\"button\"\n      [attr.aria-label]=\"'Invalid' | translate\"\n      [popover]=\"\n        errorMessage\n          ? errorMessage\n          : ('Some entries are invalid. Check the input fields with red borders.' | translate)\n      \"\n      triggers=\"focus\"\n      placement=\"left\"\n      container=\"body\"\n      *ngIf=\"!(isValid$ | async)\"\n    >\n      <i c8yIcon=\"warning\"></i>\n    </button>\n    <div class=\"m-l-auto a-s-center p-r-4\" *ngIf=\"addButtonType === AddButtonTypes.addRemove\">\n      <button\n        class=\"btn btn-dot btn-dot--danger\"\n        type=\"button\"\n        [attr.aria-label]=\"'Remove' | translate\"\n        [tooltip]=\"'Remove from selected data points' | translate\"\n        [delay]=\"500\"\n        (click)=\"addOrRemoveItem()\"\n        *ngIf=\"isSelected\"\n        [attr.data-cy]=\"'datapoint-selector-list-item--remove-datapoint-button'\"\n      >\n        <i class=\"icon-20\" c8yIcon=\"minus-circle\"></i>\n      </button>\n      <button\n        class=\"btn btn-dot text-primary\"\n        type=\"button\"\n        [attr.aria-label]=\"'Add to selected data points' | translate\"\n        [tooltip]=\"'Add to selected data points' | translate\"\n        [delay]=\"500\"\n        [disabled]=\"!(isValid$ | async)\"\n        (click)=\"addOrRemoveItem()\"\n        *ngIf=\"!isSelected\"\n        [attr.data-cy]=\"'datapoint-selector-list-item--add-datapoint-button'\"\n      >\n        <i class=\"text-primary icon-20\" c8yIcon=\"plus-circle\"></i>\n      </button>\n    </div>\n    <button\n        *ngIf=\"addButtonType === AddButtonTypes.select\"\n        class=\"btn btn-default btn-sm m-l-auto\"\n        type=\"button\"\n        [attr.aria-label]=\"'Select' | translate\"\n        [tooltip]=\"'Select data point' | translate\"\n        [delay]=\"500\"\n        (click)=\"addOrRemoveItem()\"\n      >{{ 'Select' | translate }}</button>\n  </div>\n\n  <c8y-li-action\n    *ngIf=\"optionToRemove\"\n    [icon]=\"'minus-circle'\"\n    [label]=\"'Remove from list' | translate\"\n    (click)=\"remove()\"\n  ></c8y-li-action>\n  <c8y-li-action\n    *ngFor=\"let action of actions\"\n    [icon]=\"action.icon\"\n    [label]=\"action.label\"\n    (click)=\"action.callback(formGroup.value)\"\n  ></c8y-li-action>\n  <c8y-li-collapse *ngIf=\"editable\">\n    <div class=\"data-point-details\">\n      <ul class=\"list-unstyled small m-b-16\">\n        <li class=\"p-t-4 p-b-4 d-flex separator-top-bottom\">\n          <label class=\"small m-b-0 m-r-8 a-s-start text-muted\" translate>Fragment</label>\n          <span class=\"m-l-auto\">\n            <c8y-highlight\n              [text]=\"formGroup.value.fragment\"\n              [pattern]=\"highlightText\"\n              [shouldTrimPattern]=\"true\"\n            ></c8y-highlight>\n          </span>\n        </li>\n        <li class=\"p-t-4 p-b-4 d-flex separator-bottom\">\n          <label class=\"small m-b-0 m-r-8 a-s-start text-muted\" translate>Series</label>\n          <span class=\"m-l-auto\">\n            <c8y-highlight\n              [text]=\"formGroup.value.series\"\n              [pattern]=\"highlightText\"\n              [shouldTrimPattern]=\"true\"\n            ></c8y-highlight>\n          </span>\n        </li>\n      </ul>\n      <div\n        class=\"form-group form-group-sm\"\n        *ngIf=\"datapointLibraryEntries && datapointLibraryEntries | async as libraryEntries\"\n      >\n        <label>\n          {{ 'Data point template' | translate }} \n          <button\n            class=\"btn-help btn-help--sm\"\n            type=\"button\"\n            [attr.aria-label]=\"'Help' | translate\"\n            [popover]=\"datapointHintPopoverTemplate\"\n            (click)=\"$event.stopPropagation()\"\n            triggers=\"focus\"\n            placement=\"top\"\n          ></button>\n        </label>\n      \n\n        <ng-template #datapointHintPopoverTemplate>\n          {{\n            'Using a data point template sets color, label, unit and ranges. Removing the template allows you to set the values manually.'\n              | translate\n          }}\n        </ng-template>\n        <div class=\"input-group input-group-sm\">\n          <c8y-typeahead\n            class=\"flex-grow\"\n            [placeholder]=\"'No template' | translate\"\n            [ngModel]=\"formGroup.value.__template ? formGroup.value.details : undefined\"\n            [ngModelOptions]=\"{ standalone: true }\"\n            (onSearch)=\"setPipe($event)\"\n            [displayProperty]=\"'label'\"\n            [hideNew]=\"true\"\n            *ngIf=\"datapointLibraryEntries\"\n            [disabled]=\"isSelected && disableTypeaheadIfSelected\"\n          >\n            <c8y-li\n              class=\"p-l-8 p-r-8 c8y-list__item--link interact\"\n              *c8yFor=\"\n                let item of datapointLibraryEntries;\n                loadMore: 'auto';\n                pipe: filterPipe;\n                notFound: notFoundTemplate\n              \"\n              (click)=\"dataPointTemplateSelected(item)\"\n              [active]=\"formGroup.value.__template === item.id\"\n              [attr.role]=\"'menuitem'\"\n            >\n              <c8y-highlight [text]=\"item.c8y_Kpi?.label\" [pattern]=\"pattern\"></c8y-highlight>\n              <c8y-li-icon icon=\"circle\" [style.color]=\"item.c8y_Kpi?.color\"></c8y-li-icon>\n            </c8y-li>\n            <ng-template #notFoundTemplate>\n              <c8y-li class=\"bg-level-2 p-8\" *ngIf=\"pattern.length > 0\">\n                <span>No match found.</span>\n              </c8y-li>\n            </ng-template>\n          </c8y-typeahead>\n          <div class=\"input-group-btn\">\n            <button\n              class=\"btn btn-default\"\n              type=\"button\"\n              [attr.aria-label]=\"'Info' | translate\"\n              [popover]=\"datapointOverviewPopoverTemplate\"\n              placement=\"left\"\n              triggers=\"focus\"\n              container=\"body\"\n              *ngIf=\"formGroup.value.__template\"\n            >\n              <i class=\"text-info\" c8yIcon=\"info\"></i>\n            </button>\n          </div>\n          <div class=\"input-group-btn\">\n            <button\n              class=\"btn btn-default\"\n              type=\"button\"\n              tooltip=\"{{ 'Unlink data point template' | translate }}\"\n              [attr.aria-label]=\"'Unlink data point template' | translate\"\n              [delay]=\"500\"\n              placement=\"left\"\n              container=\"body\"\n              [adaptivePosition]=\"false\"\n              *ngIf=\"formGroup.value.__template && hasUnlinkTemplateOption\"\n              (click)=\"unlinkDatapointTemplate()\"\n            >\n              <i c8yIcon=\"unlink\"></i>\n            </button>\n          </div>\n        </div>\n      </div>\n      <ng-template #datapointOverviewPopoverTemplate>\n        <c8y-datapoint-template-popover\n          [datapoint]=\"formGroup.value.details\"\n        ></c8y-datapoint-template-popover>\n      </ng-template>\n      <c8y-datapoint-attributes-form\n        *ngIf=\"defaultFormOptions\"\n        [showTarget]=\"defaultFormOptions.showTarget\"\n        [showRange]=\"defaultFormOptions.showRange\"\n        [showYellowRange]=\"defaultFormOptions.showYellowRange\"\n        [showRedRange]=\"defaultFormOptions.showRedRange\"\n        [showChart]=\"defaultFormOptions.showChart\"\n        [showFormIfTemplateWasSelected]=\"defaultFormOptions.showFormIfTemplateWasSelected\"\n        [selectableChartRenderTypes]=\"defaultFormOptions.selectableChartRenderTypes\"\n        [selectableChartLineTypes]=\"defaultFormOptions.selectableChartLineTypes\"\n        [selectableAxisTypes]=\"defaultFormOptions.selectableAxisTypes\"\n        formControlName=\"details\"\n      ></c8y-datapoint-attributes-form>\n    </div>\n  </c8y-li-collapse>\n</c8y-li>\n" }]
        }], ctorParameters: () => [{ type: i2.FormBuilder }], propDecorators: { defaultFormOptions: [{
                type: Input
            }], isSelected: [{
                type: Input
            }], isCollapsed: [{
                type: Input
            }], addButtonType: [{
                type: Input
            }], editable: [{
                type: Input
            }], showActiveToggle: [{
                type: Input
            }], activeToggleDisabled: [{
                type: Input
            }], showOptions: [{
                type: Input
            }], datapointLibraryEntries: [{
                type: Input
            }], actions: [{
                type: Input
            }], optionToRemove: [{
                type: Input
            }], hasUnlinkTemplateOption: [{
                type: Input
            }], added: [{
                type: Output
            }], removed: [{
                type: Output
            }], colorPickerDisabled: [{
                type: Input
            }], disableTypeaheadIfSelected: [{
                type: Input
            }], highlightText: [{
                type: Input
            }], dragHandle: [{
                type: ContentChild,
                args: [ListItemDragHandleComponent]
            }] } });

class IncludesDatapointPipe {
    transform(datapointList, datapoint) {
        if (!Array.isArray(datapointList) || !datapoint) {
            return false;
        }
        return datapointList.some(tmp => tmp.fragment === datapoint.fragment &&
            tmp.series === datapoint.series &&
            tmp.__target?.id === datapoint.__target?.id);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: IncludesDatapointPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: IncludesDatapointPipe, isStandalone: true, name: "includesDatapoint" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: IncludesDatapointPipe, decorators: [{
            type: Pipe,
            args: [{ name: 'includesDatapoint' }]
        }] });

class DatapointLabelPipe {
    transform(datapoint, options = { includeDevice: false, doNotUseLabel: false }) {
        let label = '';
        try {
            if (!options?.doNotUseLabel && datapoint.label) {
                label = datapoint.label;
            }
            else {
                label = `${datapoint.fragment} → ${datapoint.series}`;
            }
            if (options?.includeDevice && (datapoint.__target?.name || datapoint.__target?.id)) {
                label += ` (${datapoint.__target?.name || datapoint.__target?.id})`;
            }
        }
        catch (e) {
            // nothing to do
        }
        return label;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointLabelPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: DatapointLabelPipe, isStandalone: true, name: "datapointLabel" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointLabelPipe, decorators: [{
            type: Pipe,
            args: [{ name: 'datapointLabel' }]
        }] });

class DatapointSelectorComponent {
    constructor(datapointService) {
        this.datapointService = datapointService;
        this.allowChangingContext = true;
        this.allowDatapointsFromMultipleAssets = true;
        this.selectedDatapoints = new Array();
        this.defaultActiveState = true;
        this.ignoreDatapointTemplates = false;
        this.datapointTemplatesOnly = false;
        this.guessDatapointUnit = true;
        this.allowSearch = true;
        this.hideSelection = false;
        this.itemsEditable = true;
        this.searchString = '';
        this.maxNumberOfDatapoints = 50;
        this.AddButtonTypes = AddButtonTypes;
        this.loadingDatapoints = false;
        this.assetSelection = new BehaviorSubject(null);
        this.emptyStateSubtitleWhenNoMatchingDataPoints = gettext('Try another search term.');
        this.emptyStateSubtitleWhenNoDataPointsInAsset = gettext('Select an asset with data points from the list.');
        this.searchString$ = new BehaviorSubject('');
        this.touched = false;
    }
    ngOnInit() {
        this.selectorTitle = this.datapointTemplatesOnly
            ? gettext('Available data point templates')
            : gettext('Available data points');
        this.emptyStateTitle = this.datapointTemplatesOnly
            ? gettext('No data point templates to display.')
            : gettext('No data points to display.');
        this.selectedListTitle = this.datapointTemplatesOnly
            ? gettext('Selected data point templates')
            : gettext('Selected data points');
        this.setupObservables();
        if (!this.ignoreDatapointTemplates) {
            this.datapointLibraryEntries = from(this.datapointService.getFirstDatapointLibraryPage());
        }
        if (this.contextAsset) {
            this.selectionChanged(this.contextAsset);
        }
    }
    writeValue(obj) {
        this.selectedDatapoints = obj;
    }
    registerOnChange(fn) {
        this.onChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    datapointAdded(dp) {
        this.markAsTouched();
        dp.__active = this.defaultActiveState;
        if (this.guessDatapointUnit && !dp.unit) {
            this.datapointService.guessUnitOfDatapoint(dp.fragment, dp.series, dp.__target).then(unit => {
                dp.unit = unit;
            });
        }
        this.selectedDatapoints = [...this.selectedDatapoints, dp];
        this.emitCurrentSelection();
    }
    datapointRemoved(dp) {
        this.markAsTouched();
        this.selectedDatapoints = this.selectedDatapoints.filter(tmp => tmp.fragment !== dp.fragment ||
            tmp.series !== dp.series ||
            tmp.__target?.id !== dp.__target?.id);
        this.emitCurrentSelection();
    }
    selectionChanged(evt) {
        if (Array.isArray(evt) && evt.length !== 0) {
            return this.selectAsset(evt[0]);
        }
        if (!Array.isArray(evt) && evt.items) {
            return this.selectionChanged(evt.items);
        }
        if (!Array.isArray(evt) && evt.id) {
            return this.selectAsset(evt);
        }
        // reset selection
        this.assetSelection.next(null);
    }
    trackByFn(_index, item) {
        return `${item.fragment}-${item.__target?.id}-${item.series}`;
    }
    searchStringChanged(newValue = '') {
        this.searchString$.next(newValue);
        this.searchString = newValue;
    }
    setupObservables() {
        this.datapoints$ = this.assetSelection.pipe(tap(() => {
            this.loadingDatapoints = true;
        }), switchMap(asset => asset?.id
            ? this.datapointService.getDatapointsOfAsset(asset, this.ignoreDatapointTemplates, this.datapointTemplatesOnly)
            : []), tap(() => (this.loadingDatapoints = false)), shareReplay(1));
        this.searchStringChanges$ = this.searchString$.pipe(distinctUntilChanged(), debounceTime(500), shareReplay(1));
        this.filteredDatapoints$ = combineLatest([this.searchStringChanges$, this.datapoints$]).pipe(map(([searchString, datapoints]) => {
            if (!searchString) {
                return datapoints;
            }
            const lowerCaseSearchString = searchString.toLowerCase();
            return datapoints.filter(datapoint => this.includesSearchString(datapoint, lowerCaseSearchString));
        }), map(filtered => filtered.slice(0, this.maxNumberOfDatapoints)));
    }
    selectAsset(asset) {
        this.assetSelection.next(asset);
        this.searchStringChanged();
        if (!this.allowDatapointsFromMultipleAssets) {
            this.clearSelection();
        }
    }
    clearSelection() {
        this.selectedDatapoints = [];
        this.emitCurrentSelection();
    }
    emitCurrentSelection() {
        this.onChange(this.selectedDatapoints);
    }
    markAsTouched() {
        if (!this.touched) {
            this.onTouched();
            this.touched = true;
        }
    }
    includesSearchString(datapoint, lowerCaseSearchString) {
        const label = datapoint.label?.toLowerCase();
        if (label && label.includes(lowerCaseSearchString)) {
            return true;
        }
        const fragment = datapoint.fragment?.toLowerCase();
        if (fragment && fragment.includes(lowerCaseSearchString)) {
            return true;
        }
        const series = datapoint.series?.toLowerCase();
        if (series && series.includes(lowerCaseSearchString)) {
            return true;
        }
        return false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorComponent, deps: [{ token: DatapointLibraryService }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DatapointSelectorComponent, isStandalone: true, selector: "c8y-datapoint-selector", inputs: { contextAsset: "contextAsset", allowChangingContext: "allowChangingContext", allowDatapointsFromMultipleAssets: "allowDatapointsFromMultipleAssets", defaultActiveState: "defaultActiveState", ignoreDatapointTemplates: "ignoreDatapointTemplates", datapointTemplatesOnly: "datapointTemplatesOnly", guessDatapointUnit: "guessDatapointUnit", allowSearch: "allowSearch", hideSelection: "hideSelection", itemsEditable: "itemsEditable" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                multi: true,
                useExisting: forwardRef(() => DatapointSelectorComponent)
            }
        ], ngImport: i0, template: "<div\n  class=\"d-grid grid__row--1 fit-h\"\n  [ngClass]=\"{\n    'grid__col--3-6-3--md': allowChangingContext && !hideSelection,\n    'grid__col--8-4--md': !allowChangingContext && !hideSelection,\n    'grid__col--4-8--md': allowChangingContext && hideSelection\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)=\"selectionChanged($event)\"\n      [container]=\"''\"\n      [config]=\"{\n        view: 'miller',\n        groupsSelectable: true,\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\">\n    <ng-template #noDeviceEmptyState>\n      <div class=\"p-16\">\n        <c8y-ui-empty-state\n          [icon]=\"'c8y-data-points'\"\n          [title]=\"emptyStateTitle | translate\"\n          [subtitle]=\"'Select an asset from the list.' | translate\"\n          [horizontal]=\"true\"\n        ></c8y-ui-empty-state>\n      </div>\n    </ng-template>\n    <ng-template #loadingData>\n      <div class=\"p-16 text-center\">\n        <c8y-loading></c8y-loading>\n      </div>\n    </ng-template>\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]=\"selectorTitle | translate\"\n        >\n          {{ selectorTitle | translate }}\n        </p>\n        <div\n          class=\"input-group input-group-search m-t-4\"\n          id=\"search\"\n          *ngIf=\"!loadingDatapoints\"\n        >\n          <input\n            class=\"form-control\"\n            placeholder=\"Search\u2026\"\n            type=\"search\"\n            [ngModel]=\"searchString\"\n            (ngModelChange)=\"searchStringChanged($event)\"\n          />\n          <span class=\"input-group-addon\">\n            <i\n              c8yIcon=\"search\"\n              *ngIf=\"!searchString; else clearSearchString\"\n            ></i>\n            <ng-template #clearSearchString>\n              <i\n                class=\"text-muted\"\n                c8yIcon=\"times\"\n                (click)=\"searchStringChanged()\"\n              ></i>\n            </ng-template>\n          </span>\n        </div>\n      </div>\n      <ng-container *ngIf=\"filteredDatapoints$ | async as filteredDatapoints; else loadingData\">\n        <ng-container *ngIf=\"!loadingDatapoints; else loadingData\">\n          <ng-container *ngIf=\"datapoints$ | async as datapoints\">\n            <div\n              class=\"p-16\"\n              *ngIf=\"!filteredDatapoints.length\"\n            >\n              <c8y-ui-empty-state\n                [icon]=\"'c8y-data-points'\"\n                [title]=\"emptyStateTitle | translate\"\n                [subtitle]=\"\n                  datapoints.length\n                    ? (emptyStateSubtitleWhenNoMatchingDataPoints | translate)\n                    : (emptyStateSubtitleWhenNoDataPointsInAsset | 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=\"\n                  datapoints.length > maxNumberOfDatapoints &&\n                  filteredDatapoints.length >= maxNumberOfDatapoints\n                \"\n              >\n                <div class=\"alert alert-warning m-b-0\">\n                  {{\n                    'Due to the large number, only a subset of data points is displayed. Use search to narrow down the number of results.'\n                      | translate\n                  }}\n                </div>\n              </c8y-list-item>\n              <c8y-datapoint-selector-list-item\n                class=\"d-contents\"\n                [ngModel]=\"dp\"\n                [isSelected]=\"selectedDatapoints | includesDatapoint: dp\"\n                [datapointLibraryEntries]=\"datapointLibraryEntries\"\n                [disableTypeaheadIfSelected]=\"true\"\n                [addButtonType]=\"hideSelection ? AddButtonTypes.select : AddButtonTypes.addRemove\"\n                (added)=\"datapointAdded($event)\"\n                (removed)=\"datapointRemoved($event)\"\n                [highlightText]=\"searchStringChanges$ | async\"\n                *ngFor=\"let dp of filteredDatapoints; trackBy: trackByFn\"\n                [editable]=\"itemsEditable\"\n              ></c8y-datapoint-selector-list-item>\n            </c8y-list-group>\n          </ng-container>\n        </ng-container>\n      </ng-container>\n    </div>\n  </div>\n  <!-- last column  -->\n  <div\n    class=\"inner-scroll bg-level-1\"\n    *ngIf=\"!hideSelection\"\n  >\n    <p\n      class=\"text-medium p-l-16 p-r-16 p-t-8 p-b-8 separator-bottom sticky-top text-truncate\"\n      [title]=\"selectedListTitle | translate\"\n    >\n      {{ selectedListTitle | translate }}\n    </p>\n    <div\n      class=\"d-flex flex-wrap gap-8 p-l-16 p-r-16 p-t-8 p-b-16\"\n      *ngIf=\"selectedDatapoints?.length\"\n    >\n      <div\n        class=\"c8y-datapoint-pill\"\n        *ngFor=\"let selectedDp of selectedDatapoints\"\n      >\n        <button\n          class=\"c8y-datapoint-pill__btn\"\n          [title]=\"'Remove' | translate\"\n          type=\"button\"\n          (click)=\"datapointRemoved(selectedDp)\"\n        >\n          <i\n            class=\"icon-14\"\n            c8yIcon=\"remove\"\n          ></i>\n        </button>\n        <div\n          class=\"c8y-datapoint-pill__label\"\n          [title]=\"selectedDp | datapointLabel: { doNotUseLabel: true, includeDevice: true }\"\n        >\n          <i\n            class=\"m-r-4 icon-14\"\n            c8yIcon=\"circle\"\n            [style.color]=\"selectedDp.color\"\n          ></i>\n          <span class=\"text-truncate\">\n            <span class=\"text-truncate\">{{ selectedDp | datapointLabel }}</span>\n            <small\n              class=\"text-muted text-10\"\n              *ngIf=\"selectedDp?.__target?.name\"\n            >\n              {{ selectedDp?.__target?.name }}\n            </small>\n          </span>\n        </div>\n      </div>\n    </div>\n    <div\n      class=\"p-r-8\"\n      *ngIf=\"!selectedDatapoints || !selectedDatapoints.length\"\n    >\n      <c8y-ui-empty-state\n        [icon]=\"'c8y-data-points'\"\n        [title]=\"emptyStateTitle | translate\"\n        [subtitle]=\"\n          'Select the asset, then on the available data points list, click on the plus button on the desired data point.'\n            | translate\n        \"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n    </div>\n  </div>\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: MillerViewComponent, selector: "c8y-asset-selector-miller", inputs: ["config", "asset", "selectedDevice", "rootNode", "container"], outputs: ["onSelected", "onClearSelected"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.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: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: DatapointSelectorListItemComponent, selector: "c8y-datapoint-selector-list-item", inputs: ["defaultFormOptions", "isSelected", "isCollapsed", "addButtonType", "editable", "showActiveToggle", "activeToggleDisabled", "showOptions", "datapointLibraryEntries", "actions", "optionToRemove", "hasUnlinkTemplateOption", "colorPickerDisabled", "disableTypeaheadIfSelected", "highlightText"], outputs: ["added", "removed"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: IncludesDatapointPipe, name: "includesDatapoint" }, { kind: "pipe", type: DatapointLabelPipe, name: "datapointLabel" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoint-selector', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            multi: true,
                            useExisting: forwardRef(() => DatapointSelectorComponent)
                        }
                    ], imports: [
                        NgClass,
                        NgIf,
                        MillerViewComponent,
                        FormsModule,
                        EmptyStateComponent,
                        LoadingComponent,
                        IconDirective,
                        ListGroupComponent,
                        ListItemComponent,
                        NgFor,
                        DatapointSelectorListItemComponent,
                        C8yTranslatePipe,
                        AsyncPipe,
                        IncludesDatapointPipe,
                        DatapointLabelPipe
                    ], template: "<div\n  class=\"d-grid grid__row--1 fit-h\"\n  [ngClass]=\"{\n    'grid__col--3-6-3--md': allowChangingContext && !hideSelection,\n    'grid__col--8-4--md': !allowChangingContext && !hideSelection,\n    'grid__col--4-8--md': allowChangingContext && hideSelection\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)=\"selectionChanged($event)\"\n      [container]=\"''\"\n      [config]=\"{\n        view: 'miller',\n        groupsSelectable: true,\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\">\n    <ng-template #noDeviceEmptyState>\n      <div class=\"p-16\">\n        <c8y-ui-empty-state\n          [icon]=\"'c8y-data-points'\"\n          [title]=\"emptyStateTitle | translate\"\n          [subtitle]=\"'Select an asset from the list.' | translate\"\n          [horizontal]=\"true\"\n        ></c8y-ui-empty-state>\n      </div>\n    </ng-template>\n    <ng-template #loadingData>\n      <div class=\"p-16 text-center\">\n        <c8y-loading></c8y-loading>\n      </div>\n    </ng-template>\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]=\"selectorTitle | translate\"\n        >\n          {{ selectorTitle | translate }}\n        </p>\n        <div\n          class=\"input-group input-group-search m-t-4\"\n          id=\"search\"\n          *ngIf=\"!loadingDatapoints\"\n        >\n          <input\n            class=\"form-control\"\n            placeholder=\"Search\u2026\"\n            type=\"search\"\n            [ngModel]=\"searchString\"\n            (ngModelChange)=\"searchStringChanged($event)\"\n          />\n          <span class=\"input-group-addon\">\n            <i\n              c8yIcon=\"search\"\n              *ngIf=\"!searchString; else clearSearchString\"\n            ></i>\n            <ng-template #clearSearchString>\n              <i\n                class=\"text-muted\"\n                c8yIcon=\"times\"\n                (click)=\"searchStringChanged()\"\n              ></i>\n            </ng-template>\n          </span>\n        </div>\n      </div>\n      <ng-container *ngIf=\"filteredDatapoints$ | async as filteredDatapoints; else loadingData\">\n        <ng-container *ngIf=\"!loadingDatapoints; else loadingData\">\n          <ng-container *ngIf=\"datapoints$ | async as datapoints\">\n            <div\n              class=\"p-16\"\n              *ngIf=\"!filteredDatapoints.length\"\n            >\n              <c8y-ui-empty-state\n                [icon]=\"'c8y-data-points'\"\n                [title]=\"emptyStateTitle | translate\"\n                [subtitle]=\"\n                  datapoints.length\n                    ? (emptyStateSubtitleWhenNoMatchingDataPoints | translate)\n                    : (emptyStateSubtitleWhenNoDataPointsInAsset | 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=\"\n                  datapoints.length > maxNumberOfDatapoints &&\n                  filteredDatapoints.length >= maxNumberOfDatapoints\n                \"\n              >\n                <div class=\"alert alert-warning m-b-0\">\n                  {{\n                    'Due to the large number, only a subset of data points is displayed. Use search to narrow down the number of results.'\n                      | translate\n                  }}\n                </div>\n              </c8y-list-item>\n              <c8y-datapoint-selector-list-item\n                class=\"d-contents\"\n                [ngModel]=\"dp\"\n                [isSelected]=\"selectedDatapoints | includesDatapoint: dp\"\n                [datapointLibraryEntries]=\"datapointLibraryEntries\"\n                [disableTypeaheadIfSelected]=\"true\"\n                [addButtonType]=\"hideSelection ? AddButtonTypes.select : AddButtonTypes.addRemove\"\n                (added)=\"datapointAdded($event)\"\n                (removed)=\"datapointRemoved($event)\"\n                [highlightText]=\"searchStringChanges$ | async\"\n                *ngFor=\"let dp of filteredDatapoints; trackBy: trackByFn\"\n                [editable]=\"itemsEditable\"\n              ></c8y-datapoint-selector-list-item>\n            </c8y-list-group>\n          </ng-container>\n        </ng-container>\n      </ng-container>\n    </div>\n  </div>\n  <!-- last column  -->\n  <div\n    class=\"inner-scroll bg-level-1\"\n    *ngIf=\"!hideSelection\"\n  >\n    <p\n      class=\"text-medium p-l-16 p-r-16 p-t-8 p-b-8 separator-bottom sticky-top text-truncate\"\n      [title]=\"selectedListTitle | translate\"\n    >\n      {{ selectedListTitle | translate }}\n    </p>\n    <div\n      class=\"d-flex flex-wrap gap-8 p-l-16 p-r-16 p-t-8 p-b-16\"\n      *ngIf=\"selectedDatapoints?.length\"\n    >\n      <div\n        class=\"c8y-datapoint-pill\"\n        *ngFor=\"let selectedDp of selectedDatapoints\"\n      >\n        <button\n          class=\"c8y-datapoint-pill__btn\"\n          [title]=\"'Remove' | translate\"\n          type=\"button\"\n          (click)=\"datapointRemoved(selectedDp)\"\n        >\n          <i\n            class=\"icon-14\"\n            c8yIcon=\"remove\"\n          ></i>\n        </button>\n        <div\n          class=\"c8y-datapoint-pill__label\"\n          [title]=\"selectedDp | datapointLabel: { doNotUseLabel: true, includeDevice: true }\"\n        >\n          <i\n            class=\"m-r-4 icon-14\"\n            c8yIcon=\"circle\"\n            [style.color]=\"selectedDp.color\"\n          ></i>\n          <span class=\"text-truncate\">\n            <span class=\"text-truncate\">{{ selectedDp | datapointLabel }}</span>\n            <small\n              class=\"text-muted text-10\"\n              *ngIf=\"selectedDp?.__target?.name\"\n            >\n              {{ selectedDp?.__target?.name }}\n            </small>\n          </span>\n        </div>\n      </div>\n    </div>\n    <div\n      class=\"p-r-8\"\n      *ngIf=\"!selectedDatapoints || !selectedDatapoints.length\"\n    >\n      <c8y-ui-empty-state\n        [icon]=\"'c8y-data-points'\"\n        [title]=\"emptyStateTitle | translate\"\n        [subtitle]=\"\n          'Select the asset, then on the available data points list, click on the plus button on the desired data point.'\n            | translate\n        \"\n        [horizontal]=\"true\"\n      ></c8y-ui-empty-state>\n    </div>\n  </div>\n</div>\n" }]
        }], ctorParameters: () => [{ type: DatapointLibraryService }], propDecorators: { contextAsset: [{
                type: Input
            }], allowChangingContext: [{
                type: Input
            }], allowDatapointsFromMultipleAssets: [{
                type: Input
            }], defaultActiveState: [{
                type: Input
            }], ignoreDatapointTemplates: [{
                type: Input
            }], datapointTemplatesOnly: [{
                type: Input
            }], guessDatapointUnit: [{
                type: Input
            }], allowSearch: [{
                type: Input
            }], hideSelection: [{
                type: Input
            }], itemsEditable: [{
                type: Input
            }] } });

class DatapointSelectorModalComponent {
    constructor(bsModal, elementRef) {
        this.bsModal = bsModal;
        this.elementRef = elementRef;
        this.allowChangingContext = true;
        this.allowSearch = true;
        this.allowDatapointsFromMultipleAssets = true;
        this.selectedDatapoints = new Array();
        this.title = gettext('Data point selector');
        this.saveButtonLabel = gettext('Add data points');
        this.guessDatapointUnit = true;
        this.defaultActiveState = true;
        this.finishWithFirstSelection = false;
        this.ignoreDatapointTemplates = false;
        this.itemsEditable = true;
        this.datapointTemplatesOnly = false;
        this.assetSelectorConfig = {};
        this.result = new Promise((resolve, reject) => {
            this.save = resolve;
            this.cancel = reject;
        });
    }
    ngOnInit() {
        this.applyWorkaroundForAngularJSModalsThatMightBeOpenedInParallel();
    }
    saveChanges() {
        this.bsModal.hide();
        this.save(this.selectedDatapoints);
    }
    close() {
        this.bsModal.hide();
        this.cancel();
    }
    selectionChange(selection) {
        this.selectedDatapoints = selection;
        if (this.finishWithFirstSelection) {
            this.saveChanges();
        }
    }
    /**
     * changes the z-index of the modal, to make sure this modal is on top.
     * required as angularJS modals are placing them selves on top via adjusting z-index.
     * while angular modals use the order within the dom for this..
     */
    applyWorkaroundForAngularJSModalsThatMightBeOpenedInParallel() {
        const modalContainer = get(this.elementRef, 'nativeElement.parentElement.parentElement.parentElement');
        modalContainer.style.zIndex = '1060';
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorModalComponent, deps: [{ token: i1$1.BsModalRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DatapointSelectorModalComponent, isStandalone: true, selector: "c8y-datapoint-selector-modal", ngImport: i0, template: "<div class=\"modal-header separator\">\n  <h4 id=\"modal-title\" class=\"text-medium\">{{ title | translate }}</h4>\n</div>\n<div class=\"modal-inner-scroll modal-inner-scroll--fixed\" id=\"modal-body\">\n  <c8y-datapoint-selector\n    [contextAsset]=\"contextAsset\"\n    [guessDatapointUnit]=\"guessDatapointUnit\"\n    [allowDatapointsFromMultipleAssets]=\"allowDatapointsFromMultipleAssets\"\n    [allowChangingContext]=\"allowChangingContext\"\n    [defaultActiveState]=\"defaultActiveState\"\n    [allowSearch]=\"allowSearch\"\n    [hideSelection]=\"finishWithFirstSelection\"\n    [ignoreDatapointTemplates]=\"ignoreDatapointTemplates\"\n    [datapointTemplatesOnly]=\"datapointTemplatesOnly\"\n    [itemsEditable]=\"itemsEditable\"\n    [ngModel]=\"selectedDatapoints\"\n    (ngModelChange)=\"selectionChange($event)\"\n  ></c8y-datapoint-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]=\"!selectedDatapoints?.length\"\n    (click)=\"saveChanges()\"\n    *ngIf=\"!finishWithFirstSelection\"\n  >\n    {{ saveButtonLabel | translate }}\n  </button>\n</div>\n", dependencies: [{ kind: "component", type: DatapointSelectorComponent, selector: "c8y-datapoint-selector", inputs: ["contextAsset", "allowChangingContext", "allowDatapointsFromMultipleAssets", "defaultActiveState", "ignoreDatapointTemplates", "datapointTemplatesOnly", "guessDatapointUnit", "allowSearch", "hideSelection", "itemsEditable"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorModalComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoint-selector-modal', imports: [DatapointSelectorComponent, FormsModule, C8yTranslateDirective, NgIf, C8yTranslatePipe], template: "<div class=\"modal-header separator\">\n  <h4 id=\"modal-title\" class=\"text-medium\">{{ title | translate }}</h4>\n</div>\n<div class=\"modal-inner-scroll modal-inner-scroll--fixed\" id=\"modal-body\">\n  <c8y-datapoint-selector\n    [contextAsset]=\"contextAsset\"\n    [guessDatapointUnit]=\"guessDatapointUnit\"\n    [allowDatapointsFromMultipleAssets]=\"allowDatapointsFromMultipleAssets\"\n    [allowChangingContext]=\"allowChangingContext\"\n    [defaultActiveState]=\"defaultActiveState\"\n    [allowSearch]=\"allowSearch\"\n    [hideSelection]=\"finishWithFirstSelection\"\n    [ignoreDatapointTemplates]=\"ignoreDatapointTemplates\"\n    [datapointTemplatesOnly]=\"datapointTemplatesOnly\"\n    [itemsEditable]=\"itemsEditable\"\n    [ngModel]=\"selectedDatapoints\"\n    (ngModelChange)=\"selectionChange($event)\"\n  ></c8y-datapoint-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]=\"!selectedDatapoints?.length\"\n    (click)=\"saveChanges()\"\n    *ngIf=\"!finishWithFirstSelection\"\n  >\n    {{ saveButtonLabel | translate }}\n  </button>\n</div>\n" }]
        }], ctorParameters: () => [{ type: i1$1.BsModalRef }, { type: i0.ElementRef }] });

class DatapointSelectorService {
    constructor(modal) {
        this.modal = modal;
    }
    selectDataPoints(initialState = {}) {
        const modal = this.modal.show(DatapointSelectorModalComponent, {
            ignoreBackdropClick: true,
            keyboard: false,
            initialState,
            ariaDescribedby: 'modal-body',
            ariaLabelledBy: 'modal-title',
            class: 'modal-lg'
        });
        const content = modal.content;
        return content.result;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorService, deps: [{ token: i1$1.BsModalService }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorService, decorators: [{
            type: Injectable,
            args: [{ providedIn: 'root' }]
        }], ctorParameters: () => [{ type: i1$1.BsModalService }] });

class DatapointSelectionListComponent {
    constructor(datapointSelector, datapointLibrary, formBuilder, widgetComponent) {
        this.datapointSelector = datapointSelector;
        this.datapointLibrary = datapointLibrary;
        this.formBuilder = formBuilder;
        this.widgetComponent = widgetComponent;
        this.actions = [];
        /**
         * Enable or disable drag and drop functionality.
         */
        this.allowDragAndDrop = true;
        this.config = {};
        this.defaultFormOptions = {};
        /**
         * Minimum number of active datapoints required in the list.
         */
        this.minActiveCount = 1;
        this.resolveContext = true;
        this.listTitle = '';
        this.maxActiveCountReached = false;
        this.AddButtonTypes = AddButtonTypes;
        this.usedValidators = {};
        this.formArray = this.formBuilder.array([]);
        this.isValid = this.formArray.statusChanges.pipe(map(status => status === 'VALID'));
        this.datapointLibraryEntries = from(this.datapointLibrary.getFirstDatapointLibraryPage()).pipe(shareReplay());
        this.change = this.formArray.valueChanges.pipe(map(res => this.transformValue(res)));
    }
    ngOnChanges(changes) {
        if (!changes.maxActiveCount && !changes.minActiveCount) {
            return;
        }
        if (changes.maxActiveCount) {
            this.usedValidators.maxActiveCount = C8yValidators.maxActiveCount(this.maxActiveCount);
        }
        if (changes.minActiveCount) {
            this.usedValidators.minActiveCount = C8yValidators.minActiveCount(this.minActiveCount);
        }
        const validators = Object.values(this.usedValidators);
        this.formArray.setValidators(validators);
    }
    registerOnTouched(fn) {
        this.formArray.valueChanges.pipe(take(1)).subscribe(fn);
    }
    validate(_control) {
        return this.formArray.valid ? null : { formInvalid: {} };
    }
    ngOnInit() {
        const context = this.widgetComponent?.context;
        if (context?.id && this.resolveContext) {
            const { name, id, c8y_IsDevice } = context;
            this.config.contextAsset = { name, id, c8y_IsDevice };
        }
    }
    writeValue(obj) {
        this.formArray.clear();
        if (obj?.length) {
            obj.forEach(val => {
                const formgroup = this.formBuilder.group({ details: [] });
                formgroup.patchValue({ details: val });
                this.formArray.push(formgroup);
            });
        }
        this.calculateMaxActiveCount();
    }
    registerOnChange(fn) {
        this.formArray.valueChanges
            .pipe(map(res => this.transformValue(res)), 
        // check maxActiveCount
        tap(() => {
            this.calculateMaxActiveCount();
        }))
            .subscribe(fn);
    }
    add() {
        const allowChangingContext = !this.widgetComponent?.isDeviceTypeDashboard && this.config?.allowChangingContext !== false;
        this.datapointSelector
            .selectDataPoints({
            ...(this.config || {}),
            selectedDatapoints: this.transformValue(this.formArray.value),
            defaultActiveState: true,
            allowChangingContext,
            allowSearch: !this.config?.contextAsset
        })
            .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)));
    }
    calculateMaxActiveCount() {
        if (this.maxActiveCount) {
            const currentlyActive = this.formArray.value.filter(tmp => tmp.details?.__active).length;
            this.maxActiveCountReached = currentlyActive >= this.maxActiveCount;
        }
        this.maxActiveCountReached = false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectionListComponent, deps: [{ token: DatapointSelectorService }, { token: DatapointLibraryService }, { token: i2.FormBuilder }, { token: i4.WidgetConfigComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: DatapointSelectionListComponent, isStandalone: true, selector: "c8y-datapoint-selection-list", inputs: { actions: "actions", allowDragAndDrop: "allowDragAndDrop", config: "config", defaultFormOptions: "defaultFormOptions", maxActiveCount: "maxActiveCount", minActiveCount: "minActiveCount", resolveContext: "resolveContext", listTitle: "listTitle" }, outputs: { isValid: "isValid", change: "change" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                multi: true,
                useExisting: forwardRef(() => DatapointSelectionListComponent)
            },
            {
                provide: NG_VALIDATORS,
                useExisting: forwardRef(() => DatapointSelectionListComponent),
                multi: true
            }
        ], usesOnChanges: true, ngImport: i0, template: "<div class=\"card-header separator sticky-top bg-inherit\">\n  <span\n    class=\"card-title h4\"\n    *ngIf=\"listTitle\"\n  >\n    {{ listTitle | translate }}\n  </span>\n  <span\n    class=\"card-title h4\"\n    *ngIf=\"!listTitle\"\n  >\n    {{ 'Data points' | translate }}\n  </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]=\"!allowDragAndDrop || formArray.controls?.length < 2\"\n>\n  <div\n    class=\"alert alert-warning m-t-8\"\n    role=\"alert\"\n    ngNonBindable\n    *ngIf=\"formArray.errors?.minActiveCount\"\n    translate\n    [translateParams]=\"formArray.errors?.minActiveCount\"\n  >\n    At least {{ minActive }} active data points must be selected.\n  </div>\n\n  <div\n    class=\"alert alert-warning m-t-8\"\n    role=\"alert\"\n    ngNonBindable\n    *ngIf=\"formArray.errors?.maxActiveCount\"\n    translate\n    [translateParams]=\"formArray.errors?.maxActiveCount\"\n  >\n    At maximum {{ maxActive }} active data points are allowed to be selected.\n  </div>\n\n  <ng-content select=\".alert\"></ng-content>\n\n  <div\n    class=\"p-t-8\"\n    *ngIf=\"!formArray.controls?.length\"\n  >\n    <c8y-ui-empty-state\n      class=\"p-t-8\"\n      [icon]=\"'c8y-data-points'\"\n      [title]=\"'No data points to display.' | translate\"\n      [subtitle]=\"'Add your first data point.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </div>\n  <div\n    [formGroup]=\"dpForm\"\n    *ngFor=\"let dpForm of formArray.controls; let index = index\"\n  >\n    <c8y-datapoint-selector-list-item\n      class=\"d-block\"\n      [defaultFormOptions]=\"defaultFormOptions\"\n      [activeToggleDisabled]=\"maxActiveCountReached\"\n      [showActiveToggle]=\"true\"\n      [addButtonType]=\"AddButtonTypes.none\"\n      [showOptions]=\"true\"\n      [editable]=\"true\"\n      [colorPickerDisabled]=\"false\"\n      [actions]=\"actions\"\n      [optionToRemove]=\"true\"\n      [datapointLibraryEntries]=\"datapointLibraryEntries\"\n      [hasUnlinkTemplateOption]=\"true\"\n      formControlName=\"details\"\n      (removed)=\"onItemRemoved(index)\"\n      cdkDrag\n    >\n      <c8y-li-drag-handle\n        title=\"{{ 'Click and drag to reorder' | translate }}\"\n        cdkDragHandle\n      >\n        <i c8yIcon=\"drag-reorder\"></i>\n      </c8y-li-drag-handle>\n    </c8y-datapoint-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]=\"'Add data point' | translate\"\n    type=\"button\"\n    data-cy=\"c8y-datapoint-selection-list--add-datapoint-button\"\n    (click)=\"add()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add data point' | translate }}\n  </button>\n</div>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ListGroupComponent, selector: "c8y-list-group" }, { kind: "directive", type: 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: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: DatapointSelectorListItemComponent, selector: "c8y-datapoint-selector-list-item", inputs: ["defaultFormOptions", "isSelected", "isCollapsed", "addButtonType", "editable", "showActiveToggle", "activeToggleDisabled", "showOptions", "datapointLibraryEntries", "actions", "optionToRemove", "hasUnlinkTemplateOption", "colorPickerDisabled", "disableTypeaheadIfSelected", "highlightText"], outputs: ["added", "removed"] }, { kind: "directive", type: 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: "component", type: ListItemDragHandleComponent, selector: "c8y-list-item-drag-handle, c8y-li-drag-handle" }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectionListComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoint-selection-list', providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            multi: true,
                            useExisting: forwardRef(() => DatapointSelectionListComponent)
                        },
                        {
                            provide: NG_VALIDATORS,
                            useExisting: forwardRef(() => DatapointSelectionListComponent),
                            multi: true
                        }
                    ], imports: [
                        NgIf,
                        ListGroupComponent,
                        CdkDropList,
                        C8yTranslateDirective,
                        EmptyStateComponent,
                        NgFor,
                        FormsModule,
                        ReactiveFormsModule,
                        DatapointSelectorListItemComponent,
                        CdkDrag,
                        ListItemDragHandleComponent,
                        CdkDragHandle,
                        IconDirective,
                        C8yTranslatePipe
                    ], template: "<div class=\"card-header separator sticky-top bg-inherit\">\n  <span\n    class=\"card-title h4\"\n    *ngIf=\"listTitle\"\n  >\n    {{ listTitle | translate }}\n  </span>\n  <span\n    class=\"card-title h4\"\n    *ngIf=\"!listTitle\"\n  >\n    {{ 'Data points' | translate }}\n  </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]=\"!allowDragAndDrop || formArray.controls?.length < 2\"\n>\n  <div\n    class=\"alert alert-warning m-t-8\"\n    role=\"alert\"\n    ngNonBindable\n    *ngIf=\"formArray.errors?.minActiveCount\"\n    translate\n    [translateParams]=\"formArray.errors?.minActiveCount\"\n  >\n    At least {{ minActive }} active data points must be selected.\n  </div>\n\n  <div\n    class=\"alert alert-warning m-t-8\"\n    role=\"alert\"\n    ngNonBindable\n    *ngIf=\"formArray.errors?.maxActiveCount\"\n    translate\n    [translateParams]=\"formArray.errors?.maxActiveCount\"\n  >\n    At maximum {{ maxActive }} active data points are allowed to be selected.\n  </div>\n\n  <ng-content select=\".alert\"></ng-content>\n\n  <div\n    class=\"p-t-8\"\n    *ngIf=\"!formArray.controls?.length\"\n  >\n    <c8y-ui-empty-state\n      class=\"p-t-8\"\n      [icon]=\"'c8y-data-points'\"\n      [title]=\"'No data points to display.' | translate\"\n      [subtitle]=\"'Add your first data point.' | translate\"\n      [horizontal]=\"true\"\n    ></c8y-ui-empty-state>\n  </div>\n  <div\n    [formGroup]=\"dpForm\"\n    *ngFor=\"let dpForm of formArray.controls; let index = index\"\n  >\n    <c8y-datapoint-selector-list-item\n      class=\"d-block\"\n      [defaultFormOptions]=\"defaultFormOptions\"\n      [activeToggleDisabled]=\"maxActiveCountReached\"\n      [showActiveToggle]=\"true\"\n      [addButtonType]=\"AddButtonTypes.none\"\n      [showOptions]=\"true\"\n      [editable]=\"true\"\n      [colorPickerDisabled]=\"false\"\n      [actions]=\"actions\"\n      [optionToRemove]=\"true\"\n      [datapointLibraryEntries]=\"datapointLibraryEntries\"\n      [hasUnlinkTemplateOption]=\"true\"\n      formControlName=\"details\"\n      (removed)=\"onItemRemoved(index)\"\n      cdkDrag\n    >\n      <c8y-li-drag-handle\n        title=\"{{ 'Click and drag to reorder' | translate }}\"\n        cdkDragHandle\n      >\n        <i c8yIcon=\"drag-reorder\"></i>\n      </c8y-li-drag-handle>\n    </c8y-datapoint-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]=\"'Add data point' | translate\"\n    type=\"button\"\n    data-cy=\"c8y-datapoint-selection-list--add-datapoint-button\"\n    (click)=\"add()\"\n  >\n    <i c8yIcon=\"plus-circle\"></i>\n    {{ 'Add data point' | translate }}\n  </button>\n</div>\n" }]
        }], ctorParameters: () => [{ type: DatapointSelectorService }, { type: DatapointLibraryService }, { type: i2.FormBuilder }, { type: i4.WidgetConfigComponent, decorators: [{
                    type: Optional
                }] }], propDecorators: { actions: [{
                type: Input
            }], allowDragAndDrop: [{
                type: Input
            }], config: [{
                type: Input
            }], defaultFormOptions: [{
                type: Input
            }], maxActiveCount: [{
                type: Input
            }], minActiveCount: [{
                type: Input
            }], resolveContext: [{
                type: Input
            }], listTitle: [{
                type: Input
            }], isValid: [{
                type: Output
            }], change: [{
                type: Output
            }] } });

class FilterDatapointsPipe {
    transform(datapoints, searchString) {
        if (!searchString || !datapoints || !Array.isArray(datapoints)) {
            return datapoints;
        }
        const lowerCaseSearchString = searchString.toLowerCase().trim();
        return datapoints.filter(datapoint => this.includesSearchStringIgnoringCasing(datapoint, lowerCaseSearchString));
    }
    includesSearchStringIgnoringCasing(datapoint, lowerCaseSearchString) {
        const label = datapoint.label?.toLowerCase();
        if (label && label.includes(lowerCaseSearchString)) {
            return true;
        }
        const fragment = datapoint.fragment?.toLowerCase();
        if (fragment && fragment.includes(lowerCaseSearchString)) {
            return true;
        }
        const series = datapoint.series?.toLowerCase();
        if (series && series.includes(lowerCaseSearchString)) {
            return true;
        }
        return false;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FilterDatapointsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: FilterDatapointsPipe, isStandalone: true, name: "filterDatapoints" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FilterDatapointsPipe, decorators: [{
            type: Pipe,
            args: [{ name: 'filterDatapoints' }]
        }] });

class DatapointSelectorModule {
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
    static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorModule, imports: [AssetSelectorModule,
            CollapseModule,
            CoreModule,
            BsDropdownModule,
            ModalModule,
            TooltipModule,
            PopoverModule,
            DragDropModule,
            DatapointSelectorComponent,
            DatapointSelectorModalComponent,
            DatapointSelectorListItemComponent,
            DatapointSelectionListComponent,
            DatapointTemplatePopoverComponent,
            IncludesDatapointPipe,
            DatapointLabelPipe,
            FilterDatapointsPipe,
            DatapointAttributesFormComponent], exports: [DatapointSelectorComponent,
            DatapointSelectorModalComponent,
            DatapointSelectorListItemComponent,
            DatapointSelectionListComponent,
            DatapointTemplatePopoverComponent,
            IncludesDatapointPipe,
            DatapointLabelPipe,
            DatapointAttributesFormComponent] }); }
    static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorModule, imports: [AssetSelectorModule,
            CollapseModule,
            CoreModule,
            BsDropdownModule,
            ModalModule,
            TooltipModule,
            PopoverModule,
            DragDropModule,
            DatapointSelectorComponent,
            DatapointSelectorModalComponent,
            DatapointSelectorListItemComponent,
            DatapointSelectionListComponent,
            DatapointAttributesFormComponent] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointSelectorModule, decorators: [{
            type: NgModule,
            args: [{
                    imports: [
                        AssetSelectorModule,
                        CollapseModule,
                        CoreModule,
                        BsDropdownModule,
                        ModalModule,
                        TooltipModule,
                        PopoverModule,
                        DragDropModule,
                        DatapointSelectorComponent,
                        DatapointSelectorModalComponent,
                        DatapointSelectorListItemComponent,
                        DatapointSelectionListComponent,
                        DatapointTemplatePopoverComponent,
                        IncludesDatapointPipe,
                        DatapointLabelPipe,
                        FilterDatapointsPipe,
                        DatapointAttributesFormComponent
                    ],
                    exports: [
                        DatapointSelectorComponent,
                        DatapointSelectorModalComponent,
                        DatapointSelectorListItemComponent,
                        DatapointSelectionListComponent,
                        DatapointTemplatePopoverComponent,
                        IncludesDatapointPipe,
                        DatapointLabelPipe,
                        DatapointAttributesFormComponent
                    ]
                }]
        }] });

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

export { AXIS_TYPES, AddButtonTypes, CHART_LINE_TYPES, CHART_RENDER_TYPES, DATAPOINT_LIBRARY_FRAGMENT, DatapointAttributesFormComponent, DatapointAttributesFormValidationService, DatapointLabelPipe, DatapointLibraryService, DatapointSelectionListComponent, DatapointSelectorComponent, DatapointSelectorListItemComponent, DatapointSelectorModalComponent, DatapointSelectorModule, DatapointSelectorService, DatapointTemplatePopoverComponent, IncludesDatapointPipe };
//# sourceMappingURL=c8y-ngx-components-datapoint-selector.mjs.map