import * as i0 from '@angular/core';
import { signal, inject, computed, ViewChild, Input, Component, Optional } from '@angular/core';
import * as i2 from '@angular/forms';
import { FormBuilder, NgForm, Validators } from '@angular/forms';
import * as i1 from '@c8y/ngx-components';
import { GainsightService, CommonModule, CoreModule, FormsModule, WidgetTimeContextDateRangeService, AGGREGATION_ICONS, AGGREGATION_TEXTS, DashboardChildComponent, WidgetActionWrapperComponent, SelectComponent, SelectItemDirective, SelectedItemsDirective } from '@c8y/ngx-components';
import { AlarmEventSelectorModule } from '@c8y/ngx-components/alarm-event-selector';
import * as i2$1 from '@c8y/ngx-components/context-dashboard';
import { WidgetConfigService } from '@c8y/ngx-components/context-dashboard';
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
import { ChartHelpersService, CHART_VIEW_CONTEXT, LEGEND_DISPLAY_OPTIONS, PRODUCT_EXPERIENCE_DATA_EXPLORER_AND_GRAPH, CHART_DISPLAY_OPTION_DEFAULTS, ChartsComponent, ChartEventsService, ChartAlarmsService } from '@c8y/ngx-components/echart';
import * as i3$1 from '@c8y/ngx-components/global-context';
import { PRESET_NAME, LocalControlsComponent, GLOBAL_CONTEXT_DISPLAY_MODE, GLOBAL_CONTEXT_SOURCE, GLOBAL_CONTEXT_EVENTS, REFRESH_OPTION, GlobalContextConnectorComponent } from '@c8y/ngx-components/global-context';
import * as i4 from 'ngx-bootstrap/popover';
import { PopoverModule } from 'ngx-bootstrap/popover';
import * as i3 from 'ngx-bootstrap/tooltip';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { Subject, takeUntil, BehaviorSubject } from 'rxjs';
import { A11yModule } from '@angular/cdk/a11y';
import * as i5 from '@angular/common';
import { CommonModule as CommonModule$1 } from '@angular/common';
import { ALARM_STATUS_LABELS } from '@c8y/client';
import * as i9 from '@c8y/ngx-components/alarms';
import { AlarmsModule } from '@c8y/ngx-components/alarms';
import { DatapointsExportSelectorComponent } from '@c8y/ngx-components/datapoints-export-selector';
import { gettext } from '@c8y/ngx-components/gettext';
import * as i1$1 from '@ngx-translate/core';
import { merge, cloneDeep } from 'lodash-es';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';

class DatapointsGraphWidgetConfigComponent {
    set config(value) {
        if (!value)
            return;
        if (this.isFirstConfigSet) {
            this._config.set({ ...value });
            this.isFirstConfigSet = false;
        }
        else {
            this._config.set({
                ...this._config(),
                dateFrom: value.dateFrom,
                dateTo: value.dateTo,
                interval: value.interval,
                refreshInterval: value.refreshInterval,
                isAutoRefreshEnabled: value.isAutoRefreshEnabled,
                aggregation: value.aggregation,
                realtime: value.realtime,
                displayMode: value.displayMode,
                refreshOption: value.refreshOption,
                dateTimeContext: value.dateTimeContext,
                datapoints: value.datapoints,
                alarmsEventsConfigs: value.alarmsEventsConfigs,
                showAdvancedChartOptions: value.showAdvancedChartOptions
            });
        }
    }
    get config() {
        return this._config();
    }
    set previewMapSet(template) {
        if (template) {
            this.widgetConfigService.setPreview(template);
            return;
        }
        this.widgetConfigService.setPreview(null);
    }
    constructor() {
        this._config = signal({}, ...(ngDevMode ? [{ debugName: "_config" }] : []));
        this.isFirstConfigSet = true;
        this.formBuilder = inject(FormBuilder);
        this.form = inject(NgForm);
        this.widgetConfigService = inject(WidgetConfigService);
        this.chartHelpersService = inject(ChartHelpersService);
        this.gainsightService = inject(GainsightService);
        this.datapointSelectionConfig = {};
        this.activeDatapointsExists = false;
        this.alarmsOrEventsHaveNoMatchingDps = false;
        this.chartViewContext = CHART_VIEW_CONTEXT.WIDGET_CONFIG;
        this.legendDisplayOptions = LEGEND_DISPLAY_OPTIONS;
        this.widgetControls = PRESET_NAME.DATAPOINTS_GRAPH;
        this.previewContextConfig = computed(() => {
            const cfg = this._config();
            return {
                dateTimeContext: cfg.dateTimeContext,
                aggregation: cfg.aggregation,
                isAutoRefreshEnabled: cfg.isAutoRefreshEnabled,
                refreshInterval: cfg.refreshInterval,
                refreshOption: cfg.refreshOption
            };
        }, ...(ngDevMode ? [{ debugName: "previewContextConfig" }] : []));
        this.destroy$ = new Subject();
        this.isInitialized = false;
        this.formGroup = this.initForm();
    }
    async ngOnInit() {
        const currentConfig = this._config();
        this.form.form.addControl('config', this.formGroup);
        this.formGroup.patchValue({ ...currentConfig }, { emitEvent: false });
        this.applyFormValuesToConfig();
        this.isInitialized = true;
        this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => {
            this.applyFormValuesToConfig();
            this.setActiveDatapointsExists();
            this.checkForMatchingDatapoints();
        });
    }
    ngOnChanges(changes) {
        if (!changes.config || changes.config.isFirstChange() || !this.isInitialized)
            return;
        this.setActiveDatapointsExists();
        this.checkForMatchingDatapoints();
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    onBeforeSave(config) {
        if (!this.formGroup.valid || !config)
            return false;
        const snapshot = { ...this._config() };
        for (const key in snapshot) {
            if (snapshot.hasOwnProperty(key)) {
                try {
                    config[key] = snapshot[key];
                }
                catch (e) {
                    // do nothing
                }
            }
        }
        this.widgetConfigService.updateConfig(snapshot, true);
        const configSummaryGS = this.chartHelpersService.getConfigSummaryForGainsight(config);
        this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_DATA_EXPLORER_AND_GRAPH.EVENTS.DATA_EXPLORER_AND_GRAPH, {
            component: PRODUCT_EXPERIENCE_DATA_EXPLORER_AND_GRAPH.COMPONENTS.DATA_EXPLORER_DETAILS,
            action: PRODUCT_EXPERIENCE_DATA_EXPLORER_AND_GRAPH.ACTIONS.DATA_GRAPH_WIDGET_CONFIG,
            ...configSummaryGS
        });
        return true;
    }
    updateTimeRangeOnRealtime(timeRange) {
        const current = this._config();
        this._config.set({
            ...current,
            ...timeRange,
            interval: current.interval || 'hours'
        });
    }
    updateDashboardTimeContext(timeProps) {
        const dateTimeContext = {
            dateFrom: new Date(timeProps.dateFrom).toISOString(),
            dateTo: new Date(timeProps.dateTo).toISOString(),
            interval: timeProps.interval
        };
        this._config.set({
            ...this._config(),
            dateTimeContext
        });
    }
    updateAggregatedSliderDatapoint(selectedDatapoint) {
        const aggregatedDatapoint = this.chartHelpersService.findMatchingDatapoint(this._config().datapoints || [], selectedDatapoint);
        this._config.set({
            ...this._config(),
            aggregatedDatapoint
        });
    }
    applyFormValuesToConfig() {
        const formValue = this.formGroup.value;
        this._config.set({
            ...this._config(),
            dataPointLegendDisplay: formValue.dataPointLegendDisplay,
            displayMarkedLine: formValue.displayMarkedLine,
            displayMarkedPoint: formValue.displayMarkedPoint,
            mergeMatchingDatapoints: formValue.mergeMatchingDatapoints,
            forceMergeDatapoints: formValue.forceMergeDatapoints,
            setYaxisStartToZero: formValue.setYaxisStartToZero,
            smoothLines: formValue.smoothLines,
            showLabelAndUnit: formValue.showLabelAndUnit,
            showSlider: formValue.showSlider,
            yAxisSplitLines: formValue.yAxisSplitLines,
            xAxisSplitLines: formValue.xAxisSplitLines,
            numberOfDecimalPlaces: formValue.numberOfDecimalPlaces,
            aggregatedDatapoint: formValue.aggregatedDatapoint
        });
    }
    checkForMatchingDatapoints() {
        const config = this._config();
        const alarmsEventsConfigs = config.alarmsEventsConfigs || [];
        const datapoints = config.datapoints || [];
        const allMatch = alarmsEventsConfigs.every(ae => datapoints.some(dp => dp.__target?.id === ae.__target?.id));
        queueMicrotask(() => {
            this.alarmsOrEventsHaveNoMatchingDps = !allMatch;
        });
    }
    initForm() {
        const initialState = this._config();
        const chartDefaults = CHART_DISPLAY_OPTION_DEFAULTS;
        const form = this.formBuilder.group({
            dataPointLegendDisplay: ['auto', []],
            displayMarkedLine: [chartDefaults.displayMarkedLine, []],
            displayMarkedPoint: [chartDefaults.displayMarkedPoint, []],
            mergeMatchingDatapoints: [chartDefaults.mergeMatchingDatapoints, []],
            forceMergeDatapoints: [chartDefaults.forceMergeDatapoints, []],
            setYaxisStartToZero: [chartDefaults.setYaxisStartToZero, []],
            smoothLines: [chartDefaults.smoothLines, []],
            showLabelAndUnit: [chartDefaults.showLabelAndUnit, []],
            displayAggregationSelection: [false, []],
            canDecoupleGlobalTimeContext: [false, []],
            showSlider: [chartDefaults.showSlider, [Validators.required]],
            yAxisSplitLines: [false, [Validators.required]],
            xAxisSplitLines: [false, [Validators.required]],
            numberOfDecimalPlaces: [
                chartDefaults.numberOfDecimalPlaces,
                [Validators.required, Validators.min(0), Validators.max(10)]
            ],
            aggregatedDatapoint: [initialState?.aggregatedDatapoint || null]
        });
        return form;
    }
    setActiveDatapointsExists() {
        const datapoints = this._config().datapoints || [];
        this.activeDatapointsExists = datapoints.filter(dp => dp.__active).length > 0;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DatapointsGraphWidgetConfigComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DatapointsGraphWidgetConfigComponent, isStandalone: true, selector: "c8y-datapoints-graph-widget-config", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [
            ChartEventsService,
            ChartAlarmsService,
            ChartHelpersService,
            WidgetTimeContextDateRangeService
        ], viewQueries: [{ propertyName: "previewMapSet", first: true, predicate: ["dataPointsGraphPreview"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\">\n  <fieldset class=\"c8y-fieldset\">\n    <legend>{{ 'Formatting' | translate }}</legend>\n    <c8y-form-group class=\"form-group-sm\">\n      <label\n        [title]=\"'Number of decimal places' | translate\"\n        translate\n      >\n        Number of decimal places\n      </label>\n      <input\n        class=\"form-control\"\n        name=\"numberOfDecimalPlaces\"\n        type=\"number\"\n        formControlName=\"numberOfDecimalPlaces\"\n        [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n      />\n      <c8y-messages\n        [show]=\"\n          formGroup.controls?.numberOfDecimalPlaces?.touched &&\n          formGroup?.controls?.numberOfDecimalPlaces?.errors\n        \"\n      ></c8y-messages>\n    </c8y-form-group>\n    <c8y-form-group class=\"form-group-sm\">\n      <label>\n        {{ 'Data point legend display' | translate }}\n      </label>\n      <div\n        class=\"c8y-select-wrapper\"\n        [formGroup]=\"formGroup\"\n      >\n        <select\n          class=\"form-control\"\n          [title]=\"'Data point legend display' | translate\"\n          id=\"dataPointLegendDisplay\"\n          formControlName=\"dataPointLegendDisplay\"\n        >\n          @for (option of legendDisplayOptions; track option) {\n            <option [ngValue]=\"option.value\">\n              {{ option.label | translate }}\n            </option>\n          }\n        </select>\n      </div>\n    </c8y-form-group>\n  </fieldset>\n\n  <fieldset class=\"c8y-fieldset\">\n    <legend>{{ 'Display options' | translate }}</legend>\n    <fieldset class=\"c8y-fieldset\">\n      <legend>{{ 'Axis' | translate }}</legend>\n      <c8y-form-group class=\"m-b-8 form-group-sm\">\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Y-axis helper lines' | translate\"\n        >\n          <input\n            name=\"yAxisSplitLines\"\n            type=\"checkbox\"\n            formControlName=\"yAxisSplitLines\"\n          />\n          <span></span>\n          <span translate>Y-axis helper lines</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'X-axis helper lines' | translate\"\n        >\n          <input\n            name=\"xAxisSplitLines\"\n            type=\"checkbox\"\n            formControlName=\"xAxisSplitLines\"\n          />\n          <span></span>\n          <span translate>X-axis helper lines</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Merge matching data points into single axis' | translate\"\n        >\n          <input\n            name=\"mergeMatchingDatapoints\"\n            type=\"checkbox\"\n            formControlName=\"mergeMatchingDatapoints\"\n          />\n          <span></span>\n          <span translate>Merge matching data points into single axis</span>\n          <button\n            class=\"btn-help\"\n            [attr.aria-label]=\"\n              'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n                | translate\n            \"\n            [popover]=\"\n              'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n                | translate\n            \"\n            triggers=\"focus\"\n            container=\"body\"\n            type=\"button\"\n            (click)=\"$event.stopPropagation()\"\n            [adaptivePosition]=\"false\"\n          ></button>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Force merge all data points into single axis' | translate\"\n        >\n          <input\n            name=\"forceMergeDatapoints\"\n            type=\"checkbox\"\n            formControlName=\"forceMergeDatapoints\"\n          />\n          <span></span>\n          <span translate>Force merge all data points into a single axis</span>\n          <button\n            class=\"btn-help\"\n            [attr.aria-label]=\"\n              'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n                | translate\n            \"\n            [popover]=\"\n              'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n                | translate\n            \"\n            triggers=\"focus\"\n            container=\"body\"\n            type=\"button\"\n            (click)=\"$event.stopPropagation()\"\n            [adaptivePosition]=\"false\"\n          ></button>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Set Y-axis start to 0' | translate\"\n        >\n          <input\n            name=\"setYaxisStartToZero\"\n            type=\"checkbox\"\n            formControlName=\"setYaxisStartToZero\"\n          />\n          <span></span>\n          <span translate>Set Y-axis start to 0</span>\n          <button\n            class=\"btn-help\"\n            [attr.aria-label]=\"\n              'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n                | translate\n            \"\n            [popover]=\"\n              'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n                | translate\n            \"\n            triggers=\"focus\"\n            container=\"body\"\n            type=\"button\"\n            (click)=\"$event.stopPropagation()\"\n            [adaptivePosition]=\"false\"\n          ></button>\n        </label>\n      </c8y-form-group>\n    </fieldset>\n    <fieldset class=\"c8y-fieldset\">\n      <legend>{{ 'Alarms & events' | translate }}</legend>\n      <c8y-form-group class=\"m-b-8 form-group-sm\">\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show vertical line on every occurrence' | translate\"\n        >\n          <input\n            name=\"displayMarkedLine\"\n            type=\"checkbox\"\n            formControlName=\"displayMarkedLine\"\n          />\n          <span></span>\n          <span translate>Show vertical line on every occurrence</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show icon when triggered' | translate\"\n        >\n          <input\n            name=\"displayMarkedPoint\"\n            type=\"checkbox\"\n            formControlName=\"displayMarkedPoint\"\n          />\n          <span></span>\n          <span translate>Show icon when triggered</span>\n          @if (alarmsOrEventsHaveNoMatchingDps) {\n            <button\n              class=\"btn-clean m-l-8\"\n              [attr.aria-label]=\"\n                'Some alarms or events have no matching data points. No icons will be shown for them.'\n                  | translate\n              \"\n              [tooltip]=\"\n                'Some alarms or events have no matching data points. No icons will be shown for them.'\n                  | translate\n              \"\n              container=\"body\"\n              type=\"button\"\n              (click)=\"$event.stopPropagation()\"\n              [adaptivePosition]=\"false\"\n            >\n              <i\n                class=\"text-warning\"\n                c8yIcon=\"exclamation-triangle\"\n              ></i>\n            </button>\n          }\n        </label>\n      </c8y-form-group>\n    </fieldset>\n    <fieldset class=\"c8y-fieldset\">\n      <legend>{{ 'Chart' | translate }}</legend>\n      <c8y-form-group class=\"m-b-8 form-group-sm\">\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show labels and units' | translate\"\n        >\n          <input\n            name=\"showLabelAndUnit\"\n            type=\"checkbox\"\n            formControlName=\"showLabelAndUnit\"\n          />\n          <span></span>\n          <span translate>Display labels and units on Y-axis</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show slider' | translate\"\n        >\n          <input\n            name=\"showSlider\"\n            type=\"checkbox\"\n            formControlName=\"showSlider\"\n          />\n          <span></span>\n          <span translate>Show slider</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show smooth lines' | translate\"\n        >\n          <input\n            name=\"smoothLines\"\n            type=\"checkbox\"\n            formControlName=\"smoothLines\"\n          />\n          <span></span>\n          <span translate>Show smooth lines</span>\n        </label>\n      </c8y-form-group>\n    </fieldset>\n  </fieldset>\n</form>\n\n<ng-template #dataPointsGraphPreview>\n  @if (config?.displayMode && config.displayMode !== 'dashboard') {\n    <c8y-local-controls\n      [controls]=\"widgetControls\"\n      [displayMode]=\"config.displayMode\"\n      [config]=\"previewContextConfig()\"\n      [disabled]=\"true\"\n    ></c8y-local-controls>\n  }\n\n  @if (activeDatapointsExists) {\n    <c8y-charts\n      class=\"d-block p-relative\"\n      [config]=\"config\"\n      [alerts]=\"alerts\"\n      [chartViewContext]=\"chartViewContext\"\n      (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n      (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n      (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n    ></c8y-charts>\n  }\n\n  @if (!activeDatapointsExists) {\n    <c8y-ui-empty-state\n      class=\"d-block m-t-24\"\n      [icon]=\"'search'\"\n      [title]=\"'No data points selected' | translate\"\n      [subtitle]=\"'Select data point to render content' | translate\"\n      data-cy=\"datapoints-graph-list--empty-state-no-data-point-selected\"\n    >\n      <p c8y-guide-docs>\n        <small\n          translate\n          ngNonBindable\n        >\n          Find out more in the\n          <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-graph\">\n            user documentation</a\n          >.\n        </small>\n      </p>\n    </c8y-ui-empty-state>\n  }\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][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: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage", "additionalMessages"] }, { kind: "directive", type: i1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i1.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i1.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { 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: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.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: "ngmodule", type: PopoverModule }, { kind: "directive", type: i4.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: LocalControlsComponent, selector: "c8y-local-controls", inputs: ["controls", "displayMode", "config", "isLoading", "disabled", "propagateAutoRefresh", "emitRefresh", "dashboardChild"], outputs: ["configChange", "refresh"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DatapointsGraphWidgetConfigComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoints-graph-widget-config', host: { class: 'd-contents' }, standalone: true, imports: [
                        CommonModule,
                        CoreModule,
                        FormsModule,
                        TooltipModule,
                        PopoverModule,
                        ChartsComponent,
                        DatapointSelectorModule,
                        AlarmEventSelectorModule,
                        LocalControlsComponent
                    ], providers: [
                        ChartEventsService,
                        ChartAlarmsService,
                        ChartHelpersService,
                        WidgetTimeContextDateRangeService
                    ], template: "<form [formGroup]=\"formGroup\">\n  <fieldset class=\"c8y-fieldset\">\n    <legend>{{ 'Formatting' | translate }}</legend>\n    <c8y-form-group class=\"form-group-sm\">\n      <label\n        [title]=\"'Number of decimal places' | translate\"\n        translate\n      >\n        Number of decimal places\n      </label>\n      <input\n        class=\"form-control\"\n        name=\"numberOfDecimalPlaces\"\n        type=\"number\"\n        formControlName=\"numberOfDecimalPlaces\"\n        [placeholder]=\"'e.g. {{ example }}' | translate: { example: 1 }\"\n      />\n      <c8y-messages\n        [show]=\"\n          formGroup.controls?.numberOfDecimalPlaces?.touched &&\n          formGroup?.controls?.numberOfDecimalPlaces?.errors\n        \"\n      ></c8y-messages>\n    </c8y-form-group>\n    <c8y-form-group class=\"form-group-sm\">\n      <label>\n        {{ 'Data point legend display' | translate }}\n      </label>\n      <div\n        class=\"c8y-select-wrapper\"\n        [formGroup]=\"formGroup\"\n      >\n        <select\n          class=\"form-control\"\n          [title]=\"'Data point legend display' | translate\"\n          id=\"dataPointLegendDisplay\"\n          formControlName=\"dataPointLegendDisplay\"\n        >\n          @for (option of legendDisplayOptions; track option) {\n            <option [ngValue]=\"option.value\">\n              {{ option.label | translate }}\n            </option>\n          }\n        </select>\n      </div>\n    </c8y-form-group>\n  </fieldset>\n\n  <fieldset class=\"c8y-fieldset\">\n    <legend>{{ 'Display options' | translate }}</legend>\n    <fieldset class=\"c8y-fieldset\">\n      <legend>{{ 'Axis' | translate }}</legend>\n      <c8y-form-group class=\"m-b-8 form-group-sm\">\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Y-axis helper lines' | translate\"\n        >\n          <input\n            name=\"yAxisSplitLines\"\n            type=\"checkbox\"\n            formControlName=\"yAxisSplitLines\"\n          />\n          <span></span>\n          <span translate>Y-axis helper lines</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'X-axis helper lines' | translate\"\n        >\n          <input\n            name=\"xAxisSplitLines\"\n            type=\"checkbox\"\n            formControlName=\"xAxisSplitLines\"\n          />\n          <span></span>\n          <span translate>X-axis helper lines</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Merge matching data points into single axis' | translate\"\n        >\n          <input\n            name=\"mergeMatchingDatapoints\"\n            type=\"checkbox\"\n            formControlName=\"mergeMatchingDatapoints\"\n          />\n          <span></span>\n          <span translate>Merge matching data points into single axis</span>\n          <button\n            class=\"btn-help\"\n            [attr.aria-label]=\"\n              'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n                | translate\n            \"\n            [popover]=\"\n              'Data points with the same min and max values will be merged into a single axis. The values must be defined in the data point configuration.'\n                | translate\n            \"\n            triggers=\"focus\"\n            container=\"body\"\n            type=\"button\"\n            (click)=\"$event.stopPropagation()\"\n            [adaptivePosition]=\"false\"\n          ></button>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Force merge all data points into single axis' | translate\"\n        >\n          <input\n            name=\"forceMergeDatapoints\"\n            type=\"checkbox\"\n            formControlName=\"forceMergeDatapoints\"\n          />\n          <span></span>\n          <span translate>Force merge all data points into a single axis</span>\n          <button\n            class=\"btn-help\"\n            [attr.aria-label]=\"\n              'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n                | translate\n            \"\n            [popover]=\"\n              'All axes will be force merged to a single axis with the scale being set to the max and min value of all axes. It\\'s recommended to use this option for data points with similar values.'\n                | translate\n            \"\n            triggers=\"focus\"\n            container=\"body\"\n            type=\"button\"\n            (click)=\"$event.stopPropagation()\"\n            [adaptivePosition]=\"false\"\n          ></button>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Set Y-axis start to 0' | translate\"\n        >\n          <input\n            name=\"setYaxisStartToZero\"\n            type=\"checkbox\"\n            formControlName=\"setYaxisStartToZero\"\n          />\n          <span></span>\n          <span translate>Set Y-axis start to 0</span>\n          <button\n            class=\"btn-help\"\n            [attr.aria-label]=\"\n              'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n                | translate\n            \"\n            [popover]=\"\n              'Sets the Y-axis minimum to 0 for all data points with positive values. If any data point includes negative values, the axis may still extend below 0. Explicitly configured minimum and maximum values take precedence over this option.'\n                | translate\n            \"\n            triggers=\"focus\"\n            container=\"body\"\n            type=\"button\"\n            (click)=\"$event.stopPropagation()\"\n            [adaptivePosition]=\"false\"\n          ></button>\n        </label>\n      </c8y-form-group>\n    </fieldset>\n    <fieldset class=\"c8y-fieldset\">\n      <legend>{{ 'Alarms & events' | translate }}</legend>\n      <c8y-form-group class=\"m-b-8 form-group-sm\">\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show vertical line on every occurrence' | translate\"\n        >\n          <input\n            name=\"displayMarkedLine\"\n            type=\"checkbox\"\n            formControlName=\"displayMarkedLine\"\n          />\n          <span></span>\n          <span translate>Show vertical line on every occurrence</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show icon when triggered' | translate\"\n        >\n          <input\n            name=\"displayMarkedPoint\"\n            type=\"checkbox\"\n            formControlName=\"displayMarkedPoint\"\n          />\n          <span></span>\n          <span translate>Show icon when triggered</span>\n          @if (alarmsOrEventsHaveNoMatchingDps) {\n            <button\n              class=\"btn-clean m-l-8\"\n              [attr.aria-label]=\"\n                'Some alarms or events have no matching data points. No icons will be shown for them.'\n                  | translate\n              \"\n              [tooltip]=\"\n                'Some alarms or events have no matching data points. No icons will be shown for them.'\n                  | translate\n              \"\n              container=\"body\"\n              type=\"button\"\n              (click)=\"$event.stopPropagation()\"\n              [adaptivePosition]=\"false\"\n            >\n              <i\n                class=\"text-warning\"\n                c8yIcon=\"exclamation-triangle\"\n              ></i>\n            </button>\n          }\n        </label>\n      </c8y-form-group>\n    </fieldset>\n    <fieldset class=\"c8y-fieldset\">\n      <legend>{{ 'Chart' | translate }}</legend>\n      <c8y-form-group class=\"m-b-8 form-group-sm\">\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show labels and units' | translate\"\n        >\n          <input\n            name=\"showLabelAndUnit\"\n            type=\"checkbox\"\n            formControlName=\"showLabelAndUnit\"\n          />\n          <span></span>\n          <span translate>Display labels and units on Y-axis</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show slider' | translate\"\n        >\n          <input\n            name=\"showSlider\"\n            type=\"checkbox\"\n            formControlName=\"showSlider\"\n          />\n          <span></span>\n          <span translate>Show slider</span>\n        </label>\n        <label\n          class=\"c8y-checkbox\"\n          [title]=\"'Show smooth lines' | translate\"\n        >\n          <input\n            name=\"smoothLines\"\n            type=\"checkbox\"\n            formControlName=\"smoothLines\"\n          />\n          <span></span>\n          <span translate>Show smooth lines</span>\n        </label>\n      </c8y-form-group>\n    </fieldset>\n  </fieldset>\n</form>\n\n<ng-template #dataPointsGraphPreview>\n  @if (config?.displayMode && config.displayMode !== 'dashboard') {\n    <c8y-local-controls\n      [controls]=\"widgetControls\"\n      [displayMode]=\"config.displayMode\"\n      [config]=\"previewContextConfig()\"\n      [disabled]=\"true\"\n    ></c8y-local-controls>\n  }\n\n  @if (activeDatapointsExists) {\n    <c8y-charts\n      class=\"d-block p-relative\"\n      [config]=\"config\"\n      [alerts]=\"alerts\"\n      [chartViewContext]=\"chartViewContext\"\n      (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n      (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n      (updateAggregatedSliderDatapoint)=\"updateAggregatedSliderDatapoint($event)\"\n    ></c8y-charts>\n  }\n\n  @if (!activeDatapointsExists) {\n    <c8y-ui-empty-state\n      class=\"d-block m-t-24\"\n      [icon]=\"'search'\"\n      [title]=\"'No data points selected' | translate\"\n      [subtitle]=\"'Select data point to render content' | translate\"\n      data-cy=\"datapoints-graph-list--empty-state-no-data-point-selected\"\n    >\n      <p c8y-guide-docs>\n        <small\n          translate\n          ngNonBindable\n        >\n          Find out more in the\n          <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#data-point-graph\">\n            user documentation</a\n          >.\n        </small>\n      </p>\n    </c8y-ui-empty-state>\n  }\n</ng-template>\n" }]
        }], ctorParameters: () => [], propDecorators: { config: [{
                type: Input
            }], previewMapSet: [{
                type: ViewChild,
                args: ['dataPointsGraphPreview']
            }] } });

class DatapointsGraphWidgetViewComponent {
    set config(value) {
        // Special case: sync the config with migrated values.
        // This is needed to reflect migrated states in the widget config.
        const migratedConfig = this.widgetConfigMigrationService.migrateWidgetConfig(value);
        const newConfig = merge(value, migratedConfig);
        this.displayConfig = cloneDeep(newConfig);
    }
    get config() {
        throw Error('"config" property should not be referenced in view component to avoid mutating data.');
    }
    constructor(translate, dashboardContextComponent, widgetConfigMigrationService, widgetTimeContextDateRangeService, cdr) {
        this.translate = translate;
        this.dashboardContextComponent = dashboardContextComponent;
        this.widgetConfigMigrationService = widgetConfigMigrationService;
        this.widgetTimeContextDateRangeService = widgetTimeContextDateRangeService;
        this.cdr = cdr;
        this.events = [];
        this.alarms = [];
        this.AGGREGATION_ICONS = AGGREGATION_ICONS;
        this.AGGREGATION_TEXTS = AGGREGATION_TEXTS;
        this.datapointsOutOfSync = new Map();
        this.hasAtLeastOneDatapointActive = true;
        this.hasAtLeastOneAlarmActive = true;
        this.isMarkedAreaEnabled = false;
        this.loadedDatapoints = [];
        this.loadedAlarmsOrEvents = [];
        this.isLoading$ = new BehaviorSubject(false);
        this.isSliderBeingDragged$ = new BehaviorSubject(false);
        this.chartViewContext = CHART_VIEW_CONTEXT.WIDGET_VIEW;
        this.dashboardChild = inject(DashboardChildComponent);
        this.displayMode = signal(GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD, ...(ngDevMode ? [{ debugName: "displayMode" }] : []));
        this.contextConfig = signal({}, ...(ngDevMode ? [{ debugName: "contextConfig" }] : []));
        this.isLinkedToGlobal = signal(undefined, ...(ngDevMode ? [{ debugName: "isLinkedToGlobal" }] : []));
        this.widgetControls = signal(PRESET_NAME.DATAPOINTS_GRAPH, ...(ngDevMode ? [{ debugName: "widgetControls" }] : []));
        this.GLOBAL_CONTEXT_DISPLAY_MODE = GLOBAL_CONTEXT_DISPLAY_MODE;
        /** Combined number of datapoints, alarms, and events */
        this.totalLegendItems = 0;
        /** Selectable items for the datapoints, alarms, events dropdown */
        this.selectableItems = [];
        /** Selected items from the dropdown */
        this.selectedItems = [];
        this.legendHelp = this.translate.instant(gettext(`<ul class="m-l-0 p-l-8 m-t-8 m-b-0">
    <li>
      <b>Visibility:</b>
      use visibility icon to toggle data point, alarm, or event visibility on the chart. At least one data point is required to display a chart.
    </li>
    <li>
      <b>Alarm details</b>
      Click alarm legend item to highlight area between alarm raised timestamp and alarm cleared timestamp.
      You can also click alarm markline on chart to highlight alarm and to pause tooltip. Click on highlighted area or legend item to cancel highlighting.
    </li>
  </ul>`));
        this.disableZoomInLabel = gettext('Disable zoom in');
        this.enableZoomInLabel = gettext('Click to enable zoom, then click and drag on the desired area in the chart.');
        this.hideDatapointLabel = gettext('Hide data point');
        this.showDatapointLabel = gettext('Show data point');
        this.destroy$ = new Subject();
        this.widgetInstanceId = crypto.randomUUID();
    }
    ngOnInit() {
        this.displayConfig?.datapoints?.forEach(dp => this.assignContextFromContextDashboard(dp));
        this.displayConfig.realtime = this.computeRealtimeFlag(this.displayConfig);
        this.displayConfig.isRealtimeEnabled = this.displayConfig.realtime;
        this.totalLegendItems =
            (this.displayConfig?.datapoints?.length || 0) +
                (this.displayConfig?.alarmsEventsConfigs?.length || 0);
        this.loadedDatapoints = (this.displayConfig?.datapoints || []).filter(dp => dp.__active);
        this.loadedAlarmsOrEvents = (this.displayConfig?.alarmsEventsConfigs || []).filter(aOrE => aOrE.__active && !aOrE.__hidden);
        if (this.totalLegendItems > 5 || this.displayConfig?.dataPointLegendDisplay === 'dropdown') {
            this.selectableItems = this.buildSelectableItems();
            // Initialize selectedItems with the currently active items
            this.selectedItems = this.selectableItems.filter(item => {
                if (item.value.type === 'DATAPOINT') {
                    return !!item.value.original.__active;
                }
                else {
                    return item.value.original.__active && !item.value.original.__hidden;
                }
            });
        }
        const displayMode = this.displayConfig.displayMode || GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD;
        this.displayMode.set(displayMode);
        const initialContextConfig = {
            dateTimeContext: this.displayConfig.dateTimeContext,
            aggregation: this.displayConfig.aggregation,
            isAutoRefreshEnabled: this.displayConfig.isAutoRefreshEnabled,
            refreshInterval: this.displayConfig.refreshInterval,
            refreshOption: this.displayConfig.refreshOption
        };
        this.contextConfig.set(initialContextConfig);
        this.updateExportConfig();
    }
    onContextChange(event) {
        this.invalidateHiddenItemsCache();
        this.contextConfig.set(event.context);
        const { context, diff } = event;
        const { dateTimeContext } = context;
        const { dateFrom, dateTo, interval } = dateTimeContext;
        const isRealtimeEnabled = this.computeRealtimeFlag(context);
        if (this.displayConfig.displayMode !== GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {
            const realtimeToggled = this.displayConfig?.realtime !== isRealtimeEnabled;
            if (realtimeToggled) {
                // When toggling realtime, we must:
                // 1. Spread ALL context properties (isAutoRefreshEnabled, refreshOption, etc.)
                //    to keep the GC wrapper in sync. Otherwise stale isAutoRefreshEnabled on
                //    displayConfig causes the wrapper's handleConfigChange() to silently
                //    re-enable auto-refresh via setAutoRefreshEnabled() on the inline component.
                // 2. Use chart's actual visible range from dataZoom to avoid date jump.
                //    GC's dateTimeContext dates don't match the chart's visible range — the chart
                //    slides forward every 1s via ChartRealtimeService independently of GC.
                // 3. Return early to skip updateInitialTimeRange(null) which resets cached time range.
                const option = this.chartComponent?.echartsInstance?.getOption();
                const dataZoom = option?.dataZoom?.[0];
                const chartDateFrom = dataZoom?.startValue
                    ? new Date(dataZoom.startValue).toISOString()
                    : dateFrom;
                const chartDateTo = dataZoom?.endValue ? new Date(dataZoom.endValue).toISOString() : dateTo;
                this.displayConfig = {
                    ...this.displayConfig,
                    ...structuredClone(context),
                    dateFrom: new Date(chartDateFrom),
                    dateTo: new Date(chartDateTo),
                    dateTimeContext: {
                        ...context.dateTimeContext,
                        dateFrom: chartDateFrom,
                        dateTo: chartDateTo
                    },
                    realtime: isRealtimeEnabled
                };
                this.updateExportConfig();
                return;
            }
            this.displayConfig = {
                ...this.displayConfig,
                ...structuredClone(context),
                dateFrom: new Date(dateFrom),
                dateTo: new Date(dateTo),
                interval,
                realtime: isRealtimeEnabled
            };
            this.updateExportConfig();
            if (this.isSliderBeingDragged$.value === true) {
                this.isSliderBeingDragged$.next(false);
                return;
            }
            this.widgetTimeContextDateRangeService.updateInitialTimeRange(null);
            return;
        }
        if (this.displayConfig?.realtime !== isRealtimeEnabled) {
            // Sync dates to avoid jumps in the chart
            this.displayConfig = merge(this.displayConfig, {
                dateTimeContext: structuredClone(context),
                dateFrom: new Date(dateFrom),
                dateTo: new Date(dateTo),
                interval
            });
            this.updateExportConfig();
            this.displayConfig = {
                ...this.displayConfig,
                realtime: isRealtimeEnabled
            };
        }
        // Realtime is a special case, we need to block "automatic" emissions from the global context
        // GC in auto mode emits every 5 seconds. We only want to react to user changes.
        if (isRealtimeEnabled &&
            diff?.dateTimeContext &&
            Object.keys(diff).length === 1 &&
            Object.keys(diff.dateTimeContext).length === 2) {
            // Sync dates to avoid jumps in the chart
            this.displayConfig = merge(this.displayConfig, {
                dateTimeContext: structuredClone(context),
                dateFrom: new Date(dateFrom),
                dateTo: new Date(dateTo),
                interval
            });
            this.updateExportConfig();
            return;
        }
        this.displayConfig = {
            ...this.displayConfig,
            ...structuredClone(context),
            dateFrom: new Date(dateFrom),
            dateTo: new Date(dateTo),
            interval
        };
        this.updateExportConfig();
        if (context.source === GLOBAL_CONTEXT_SOURCE.DASHBOARD &&
            this.displayConfig.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {
            this.widgetTimeContextDateRangeService.updateInitialTimeRange(null);
        }
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
    }
    updateDashboardTimeContext(timeProps) {
        const chartOptions = this.chartComponent?.echartsInstance?.getOption();
        const isEndZoomChanged = chartOptions?.dataZoom[0]?.end !== 100;
        // Check if widget is linked to global context
        const isLinked = this.isLinkedToGlobal() !== false;
        if (this.displayConfig.displayMode === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD && isLinked) {
            const dateTimeContext = isEndZoomChanged
                ? {
                    dateFrom: new Date(timeProps.dateFrom).toISOString(),
                    dateTo: new Date(timeProps.dateTo).toISOString(),
                    interval: timeProps.interval
                }
                : { dateFrom: new Date(timeProps.dateFrom).toISOString(), interval: timeProps.interval };
            window.dispatchEvent(new CustomEvent(GLOBAL_CONTEXT_EVENTS.UPDATE_GLOBAL_CONTEXT_HISTORY, {
                detail: {
                    type: GLOBAL_CONTEXT_EVENTS.UPDATE_GLOBAL_CONTEXT_HISTORY,
                    payload: {
                        dateTimeContext,
                        isAutoRefreshEnabled: false,
                        aggregation: this.displayConfig.aggregation,
                        source: GLOBAL_CONTEXT_SOURCE.WIDGET,
                        eventSourceId: this.widgetInstanceId
                    },
                    timestamp: Date.now()
                }
            }));
        }
        else {
            this.isSliderBeingDragged$.next(true);
            const dateTimeContext = {
                dateFrom: new Date(timeProps.dateFrom),
                dateTo: new Date(timeProps.dateTo),
                interval: timeProps.interval
            };
            this.isLinkedToGlobal.set(false);
            // Update displayConfig for internal state
            this.displayConfig = {
                ...this.displayConfig,
                dateTimeContext: structuredClone(dateTimeContext),
                dateFrom: new Date(timeProps.dateFrom),
                dateTo: new Date(timeProps.dateTo),
                interval: timeProps.interval,
                realtime: false,
                isAutoRefreshEnabled: false
            };
            // Update context config signal
            this.contextConfig.set({
                ...this.contextConfig(),
                dateTimeContext: structuredClone(dateTimeContext),
                isAutoRefreshEnabled: false
            });
        }
    }
    getDashboardChild() {
        return this.dashboardChild;
    }
    onRefresh() {
        this.displayConfig = { ...this.displayConfig };
        this.updateExportConfig();
    }
    buildSelectableItems() {
        const dpItems = (this.displayConfig.datapoints || []).map(dp => {
            return {
                label: dp.label,
                value: {
                    type: 'DATAPOINT',
                    original: dp
                }
            };
        });
        const alarmItems = (this.displayConfig.alarmsEventsConfigs || [])
            .filter(ae => ae.timelineType === 'ALARM')
            .map(alarm => {
            return {
                label: alarm.label,
                value: {
                    type: 'ALARM',
                    original: alarm
                }
            };
        });
        const eventItems = (this.displayConfig.alarmsEventsConfigs || [])
            .filter(ae => ae.timelineType === 'EVENT')
            .map(event => {
            return {
                label: event.label,
                value: {
                    type: 'EVENT',
                    original: event
                }
            };
        });
        return [...dpItems, ...alarmItems, ...eventItems];
    }
    onItemSelected(item) {
        if (item.value.type === 'DATAPOINT') {
            this.toggleChart(item.value.original);
        }
        else {
            this.toggleAlarmEventType(item.value.original);
        }
    }
    onItemDeselected(item) {
        if (item.value.type === 'DATAPOINT') {
            this.toggleChart(item.value.original);
        }
        else {
            this.toggleAlarmEventType(item.value.original);
        }
    }
    toggleChart(datapoint) {
        if (this.displayConfig?.datapoints?.filter(dp => dp.__active).length === 1 &&
            datapoint.__active) {
            // at least 1 datapoint should be active
            this.hasAtLeastOneDatapointActive = false;
            this.updateSelectedItems();
            return;
        }
        datapoint.__active = !datapoint.__active;
        this.hasAtLeastOneDatapointActive = true;
        this.updateSelectedItems();
        const getDatapointId = (dp) => `${dp.__target?.id}${dp.fragment}${dp.series}`;
        const isLoaded = this.loadedDatapoints.find(dp => getDatapointId(dp) === getDatapointId(datapoint));
        if (datapoint.__active && !isLoaded) {
            // Datapoint being shown but not loaded (or data is stale) - trigger full reload
            this.loadedDatapoints.push(datapoint);
            this.displayConfig = { ...this.displayConfig };
        }
        else {
            // Datapoint already loaded with fresh data OR being hidden - just toggle visibility in echarts
            this.chartComponent.toggleDatapointSeriesVisibility(datapoint);
        }
    }
    handleDatapointOutOfSync(dpOutOfSync) {
        const key = (dp) => dp.__target?.id + dp.fragment + dp.series;
        const dpMatch = this.displayConfig?.datapoints?.find(dp => key(dp) === key(dpOutOfSync));
        if (!dpMatch) {
            return;
        }
        this.datapointsOutOfSync.set(dpMatch, true);
    }
    handleDatapointBackInSync(dpBackInSync) {
        const key = (dp) => dp.__target?.id + dp.fragment + dp.series;
        const dpMatch = this.displayConfig?.datapoints?.find(dp => key(dp) === key(dpBackInSync));
        if (!dpMatch) {
            return;
        }
        this.datapointsOutOfSync.delete(dpMatch);
    }
    toggleMarkedArea(alarm) {
        this.enabledMarkedAreaAlarmType = alarm.filters.type;
        const params = {
            data: {
                itemType: alarm.filters.type
            }
        };
        this.chartComponent.onChartClick(params);
    }
    toggleAlarmEventType(alarmOrEvent) {
        const type = alarmOrEvent.filters.type;
        const deviceId = alarmOrEvent.__target?.id;
        const newHiddenState = !alarmOrEvent.__hidden;
        const isBeingShown = !newHiddenState;
        // Match by both type AND device to distinguish alarms from different devices
        const isSameAlarmConfig = (ae) => ae.filters.type === type && ae.__target?.id === deviceId;
        // Update __hidden in all locations
        alarmOrEvent.__hidden = newHiddenState;
        this.displayConfig.alarmsEventsConfigs?.forEach(ae => {
            if (isSameAlarmConfig(ae)) {
                ae.__hidden = newHiddenState;
            }
        });
        this.alarms.forEach(alarm => {
            if (isSameAlarmConfig(alarm)) {
                alarm.__hidden = newHiddenState;
            }
        });
        this.events.forEach(event => {
            if (isSameAlarmConfig(event)) {
                event.__hidden = newHiddenState;
            }
        });
        this.updateSelectedItems();
        const isLoaded = this.loadedAlarmsOrEvents.find(aOrE => isSameAlarmConfig(aOrE));
        if (isBeingShown && !isLoaded) {
            // Showing but not loaded - trigger pipeline to fetch data
            this.loadedAlarmsOrEvents.push(alarmOrEvent);
            this.displayConfig = { ...this.displayConfig };
        }
        else {
            // Hiding OR showing already-loaded - just toggle visibility in echarts
            this.chartComponent.toggleAlarmEventSeriesVisibility(alarmOrEvent);
        }
    }
    updateAlarmsAndEvents(alarmsEventsConfigs) {
        this.alarms = alarmsEventsConfigs.filter(alarm => alarm.timelineType === 'ALARM');
        this.events = alarmsEventsConfigs.filter(event => event.timelineType === 'EVENT');
        if (this.alarms.length === 0 || !this.alarms.find(alarm => alarm.__active)) {
            this.hasAtLeastOneAlarmActive = false;
        }
    }
    filterSeverity(eventTarget) {
        this.alarms = this.alarms.map(alarm => {
            if (!alarm.__severity) {
                alarm.__severity = [];
            }
            alarm.__severity = Object.keys(eventTarget.severityOptions).filter((severity) => eventTarget.severityOptions[severity]);
            if (!alarm.__status) {
                alarm.__status = [];
            }
            const statuses = Object.keys(ALARM_STATUS_LABELS);
            const filteredStatuses = eventTarget.showCleared
                ? statuses
                : statuses.filter(status => status !== 'CLEARED');
            alarm.__status = filteredStatuses;
            return alarm;
        });
        this.displayConfig = { ...this.displayConfig };
    }
    isLastActiveDatapoint(selectedItem) {
        if (!selectedItem) {
            return false;
        }
        if (!selectedItem?.value || selectedItem.value.type !== 'DATAPOINT') {
            return false;
        }
        // Check if this is the last active datapoint
        return !this.hasAtLeastOneDatapointActive && selectedItem.value.original.__active;
    }
    updateExportConfig() {
        const datapointDetails = this.displayConfig.datapoints
            .filter(({ __active }) => __active)
            .map(({ __target, fragment, series }) => ({
            deviceName: __target.name,
            source: __target.id,
            valueFragmentSeries: series,
            valueFragmentType: fragment
        }));
        if (datapointDetails.length === 0) {
            this.exportConfig = null;
        }
        else {
            const dtc = this.displayConfig.dateTimeContext;
            this.exportConfig = {
                aggregation: this.displayConfig.aggregation,
                dateFrom: new Date(dtc?.dateFrom || this.displayConfig.dateFrom).toISOString(),
                dateTo: new Date(dtc?.dateTo || this.displayConfig.dateTo).toISOString(),
                datapointDetails
            };
        }
    }
    updateSelectedItems() {
        const filtered = this.selectableItems.filter(item => {
            if (item.value.type === 'DATAPOINT') {
                return !!item.value.original.__active;
            }
            else {
                return item.value.original.__active && !item.value.original.__hidden;
            }
        });
        this.selectedItems = [...filtered];
        this.cdr.detectChanges();
    }
    assignContextFromContextDashboard(dpOrAlarmOrEvent) {
        if (!this.dashboardContextComponent?.isDeviceTypeDashboard) {
            return;
        }
        const context = this.dashboardContextComponent?.context;
        if (context?.id) {
            const { name, id } = context;
            dpOrAlarmOrEvent.__target = { name, id };
        }
    }
    /**
     * Remove hidden items from loaded cache so they will be reloaded when toggled visible.
     * Called when context changes (time range, aggregation, etc.) to mark hidden items data as stale.
     */
    invalidateHiddenItemsCache() {
        this.loadedDatapoints = this.loadedDatapoints.filter(dp => dp.__active);
        this.loadedAlarmsOrEvents = this.loadedAlarmsOrEvents.filter(aOrE => aOrE.__active && !aOrE.__hidden);
    }
    computeRealtimeFlag(source) {
        return source?.refreshOption === REFRESH_OPTION.LIVE && !!source?.isAutoRefreshEnabled;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DatapointsGraphWidgetViewComponent, deps: [{ token: i1$1.TranslateService }, { token: i2$1.ContextDashboardComponent, optional: true }, { token: i3$1.WidgetConfigMigrationService }, { token: i1.WidgetTimeContextDateRangeService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: DatapointsGraphWidgetViewComponent, isStandalone: true, selector: "c8y-datapoints-graph-widget-view", inputs: { config: "config" }, providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], viewQueries: [{ propertyName: "chartComponent", first: true, predicate: ChartsComponent, descendants: true }], ngImport: i0, template: "@if (displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {\n  <c8y-global-context-connector\n    [controls]=\"widgetControls()\"\n    [config]=\"contextConfig()\"\n    [isLoading]=\"isLoading$ | async\"\n    [dashboardChild]=\"getDashboardChild()\"\n    [linked]=\"isLinkedToGlobal()\"\n    [propagateAutoRefresh]=\"false\"\n    (configChange)=\"onContextChange($event)\"\n  ></c8y-global-context-connector>\n} @else {\n  <c8y-local-controls\n    [controls]=\"widgetControls()\"\n    [displayMode]=\"displayMode()\"\n    [config]=\"contextConfig()\"\n    [isLoading]=\"isLoading$ | async\"\n    [propagateAutoRefresh]=\"false\"\n    (configChange)=\"onContextChange($event)\"\n  ></c8y-local-controls>\n}\n\n<div\n  class=\"p-l-16 p-r-16\"\n  style=\"min-height: 34px\"\n>\n  <div class=\"d-flex gap-16 a-i-center\">\n    @if (hasAtLeastOneAlarmActive) {\n      <c8y-alarms-filter\n        class=\"d-contents form-group-sm min-width-0\"\n        (onFilterApplied)=\"filterSeverity($event)\"\n      ></c8y-alarms-filter>\n    }\n    @if (displayConfig?.datapoints.length > 0) {\n      <div class=\"d-flex a-i-center min-width-0\">\n        @if (\n          displayConfig.dataPointLegendDisplay === 'dropdown' ||\n          (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n        ) {\n          <c8y-select\n            class=\"min-width-0 c8y-select-v2--sm\"\n            aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n            [placeholder]=\"'Select data points, alarms or events' | translate\"\n            [multi]=\"true\"\n            [filterItems]=\"true\"\n            [(ngModel)]=\"selectedItems\"\n            (onSelect)=\"onItemSelected($event)\"\n            (onDeselect)=\"onItemDeselected($event)\"\n          >\n            @for (item of selectableItems; track item.value) {\n              <div\n                class=\"d-flex a-i-center gap-4\"\n                *c8ySelectItem=\"item.value; label: item.label\"\n              >\n                @if (\n                  !hasAtLeastOneDatapointActive &&\n                  item.value.type === 'DATAPOINT' &&\n                  item.value.original.__active\n                ) {\n                  <i\n                    class=\"text-warning m-r-4\"\n                    c8yIcon=\"exclamation-triangle\"\n                    [tooltip]=\"'At least 1 data point must be active.' | translate\"\n                    container=\"body\"\n                    data-cy=\"datapoint-warning-icon\"\n                    [adaptivePosition]=\"false\"\n                  ></i>\n                }\n                @if (item.value.type === 'DATAPOINT') {\n                  <span\n                    class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n                    [style.background-color]=\"item.value.original.color\"\n                  ></span>\n                }\n                @if (item.value.type === 'ALARM') {\n                  <span\n                    class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n                    [style.background-color]=\"item.value.original.color\"\n                  >\n                    <i\n                      class=\"stroked-icon\"\n                      c8yIcon=\"bell\"\n                    ></i>\n                  </span>\n                }\n                @if (item.value.type === 'EVENT') {\n                  <span\n                    class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n                    [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n                  >\n                    <i\n                      class=\"stroked-icon\"\n                      c8yIcon=\"online1\"\n                    ></i>\n                  </span>\n                }\n                <span class=\"text-truncate d-col\">\n                  <small class=\"text-truncate\">{{ item.value.original.label }}</small>\n                  <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n                </span>\n              </div>\n            }\n            <span\n              class=\"tag tag--info chip\"\n              title=\"{{ selectedItem.label }}\"\n              *c8ySelectedItems=\"let selectedItem\"\n            >\n              <button\n                class=\"btn btn-xs btn-clean text-10\"\n                title=\"{{ selectedItem.label }}\"\n                type=\"button\"\n                (click)=\"\n                  $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n                \"\n              >\n                <i c8yIcon=\"times\"></i>\n              </button>\n              @if (isLastActiveDatapoint(selectedItem)) {\n                <i\n                  class=\"text-warning a-s-start\"\n                  c8yIcon=\"exclamation-triangle\"\n                  [tooltip]=\"'At least 1 data point must be active.' | translate\"\n                  container=\"body\"\n                  data-cy=\"datapoint-warning-icon\"\n                  [adaptivePosition]=\"false\"\n                ></i>\n              }\n              @if (selectedItem.value.type === 'DATAPOINT') {\n                <span\n                  class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                  [style.background-color]=\"selectedItem.value?.original.color || ''\"\n                ></span>\n              }\n              @if (selectedItem.value?.type === 'ALARM') {\n                <span\n                  class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                  [style.background-color]=\"selectedItem.value?.original.color || ''\"\n                >\n                  <i\n                    class=\"stroked-icon\"\n                    c8yIcon=\"bell\"\n                  ></i>\n                </span>\n              }\n              @if (selectedItem.value?.type === 'EVENT') {\n                <span\n                  class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                  [ngStyle]=\"{\n                    'background-color': selectedItem.value?.original.color || ''\n                  }\"\n                >\n                  <i\n                    class=\"stroked-icon\"\n                    c8yIcon=\"online1\"\n                  ></i>\n                </span>\n              }\n            </span>\n          </c8y-select>\n        } @else {\n          <div class=\"inner-scroll\">\n            <div class=\"p-t-4 d-flex a-i-start gap-8\">\n              @for (datapoint of displayConfig.datapoints; track datapoint) {\n                @if (datapoint.retrievalError) {\n                  <i\n                    class=\"text-warning m-l-4\"\n                    c8yIcon=\"exclamation-triangle\"\n                    [tooltip]=\"'Data point no longer exists.' | translate\"\n                    container=\"body\"\n                    [adaptivePosition]=\"false\"\n                  ></i>\n                } @else {\n                  <div\n                    class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n                    title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n                    [ngClass]=\"{ active: datapoint.__active }\"\n                  >\n                    @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n                      <i\n                        class=\"text-warning m-l-4\"\n                        c8yIcon=\"exclamation-triangle\"\n                        [tooltip]=\"'At least 1 data point must be active.' | translate\"\n                        container=\"body\"\n                        data-cy=\"datapoint-warning-icon\"\n                        [adaptivePosition]=\"false\"\n                      ></i>\n                    }\n                    <button\n                      class=\"c8y-datapoint-pill__btn\"\n                      title=\"{{\n                        (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n                      }} \"\n                      type=\"button\"\n                      data-cy=\"datapoint-toggle-visibility-btn\"\n                      (click)=\"toggleChart(datapoint)\"\n                    >\n                      <i\n                        class=\"icon-14\"\n                        [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n                      ></i>\n                    </button>\n                    <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n                      <i\n                        class=\"m-r-4 icon-14\"\n                        c8yIcon=\"circle\"\n                        [ngStyle]=\"{\n                          color: datapoint.color\n                        }\"\n                      ></i>\n                      <span\n                        class=\"text-truncate\"\n                        [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n                      >\n                        <span class=\"text-truncate text-bold\">\n                          {{ datapoint.label }}\n                        </span>\n                        <small class=\"text-muted text-10\">\n                          {{ datapoint.__target.name }}\n                        </small>\n                      </span>\n                      @if (datapointsOutOfSync.get(datapoint)) {\n                        <i\n                          class=\"text-warning m-l-4\"\n                          c8yIcon=\"exclamation-triangle\"\n                          [tooltip]=\"\n                            'Measurements received for this data point may be out of sync.'\n                              | translate\n                          \"\n                          container=\"body\"\n                          [adaptivePosition]=\"false\"\n                        ></i>\n                      }\n                    </div>\n                  </div>\n                }\n              }\n\n              @for (alarm of alarms; track alarm) {\n                <div\n                  class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n                  title=\"{{ alarm.filters.type }} \"\n                >\n                  @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n                    <i\n                      class=\"text-warning m-l-4\"\n                      c8yIcon=\"exclamation-triangle\"\n                      [tooltip]=\"\n                        'Alarm of this type is currently active and outside of the selected time range'\n                          | translate\n                      \"\n                      container=\"body\"\n                      [adaptivePosition]=\"false\"\n                    ></i>\n                  }\n                  <button\n                    class=\"c8y-alarm-pill__btn\"\n                    title=\"{{ alarm.filters.type }} \"\n                    type=\"button\"\n                    (click)=\"toggleAlarmEventType(alarm)\"\n                  >\n                    <i\n                      class=\"icon-14\"\n                      [c8yIcon]=\"\n                        alarm.__hidden || !alarm.__active\n                          ? 'eye-slash text-muted'\n                          : 'eye text-primary'\n                      \"\n                    ></i>\n                  </button>\n                  <button\n                    class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n                    (click)=\"toggleMarkedArea(alarm)\"\n                    [ngClass]=\"{\n                      active:\n                        !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n                    }\"\n                  >\n                    <span\n                      class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n                      [style.background-color]=\"alarm.color\"\n                    >\n                      <i\n                        class=\"stroked-icon\"\n                        c8yIcon=\"bell\"\n                      ></i>\n                    </span>\n                    <span\n                      class=\"text-truncate\"\n                      [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n                    >\n                      <span class=\"text-truncate text-bold\">\n                        {{ alarm.label || alarm.filters.type }}\n                      </span>\n                      <small class=\"text-muted text-10\">\n                        {{ alarm.__target.name }}\n                      </small>\n                    </span>\n                  </button>\n                </div>\n              }\n\n              @for (event of events; track event) {\n                <div\n                  class=\"c8y-event-pill pill--sm flex-no-shrink\"\n                  title=\"{{ event.filters.type }}\"\n                >\n                  <button\n                    class=\"c8y-event-pill__btn\"\n                    title=\"{{ event.filters.type }} \"\n                    type=\"button\"\n                    (click)=\"toggleAlarmEventType(event)\"\n                  >\n                    <i\n                      class=\"icon-14\"\n                      [c8yIcon]=\"\n                        event.__hidden || !event.__active\n                          ? 'eye-slash text-muted'\n                          : 'eye text-primary'\n                      \"\n                    ></i>\n                  </button>\n                  <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n                    <span\n                      class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n                      [ngStyle]=\"{ 'background-color': event.color }\"\n                    >\n                      <i\n                        class=\"stroked-icon\"\n                        c8yIcon=\"online1\"\n                      ></i>\n                    </span>\n                    <span\n                      class=\"text-truncate text-bold\"\n                      [ngClass]=\"{ 'text-muted': event.__hidden }\"\n                    >\n                      <span class=\"text-truncate\">\n                        {{ event.label || event.filters.type }}\n                      </span>\n                      <small class=\"text-muted text-10\">\n                        {{ event.__target.name }}\n                      </small>\n                    </span>\n                  </div>\n                </div>\n              }\n            </div>\n          </div>\n          <button\n            class=\"btn-help btn-help--sm m-r-8\"\n            [attr.aria-label]=\"'Help' | translate\"\n            [popover]=\"legendHelpTemplate\"\n            placement=\"left\"\n            triggers=\"focus\"\n            container=\"body\"\n            [adaptivePosition]=\"true\"\n          ></button>\n        }\n      </div>\n    }\n  </div>\n</div>\n\n@if (displayConfig !== null) {\n  <c8y-charts\n    #chart\n    [config]=\"displayConfig\"\n    [alerts]=\"alerts\"\n    [chartViewContext]=\"chartViewContext\"\n    (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n    (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n    (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n    (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n    (finishLoading)=\"this.isLoading$.next($event)\"\n    (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n  ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n  <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n\n<c8y-widget-action>\n  <c8y-datapoints-export-selector\n    [displayMode]=\"'icon-only'\"\n    [exportConfig]=\"exportConfig\"\n    [containerClass]=\"'d-contents'\"\n  ></c8y-datapoints-export-selector>\n  <button\n    class=\"btn btn-icon\"\n    [attr.aria-label]=\"'Save as image' | translate\"\n    tooltip=\"{{ 'Save as image' | translate }}\"\n    container=\"body\"\n    type=\"button\"\n    [delay]=\"500\"\n    (click)=\"chartComponent.saveAsImage()\"\n    [adaptivePosition]=\"false\"\n  >\n    <i\n      class=\"icon-14\"\n      c8yIcon=\"image-file-checked\"\n    ></i>\n  </button>\n</c8y-widget-action>\n", dependencies: [{ kind: "ngmodule", type: A11yModule }, { kind: "ngmodule", type: CommonModule$1 }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: ChartsComponent, selector: "c8y-charts", inputs: ["config", "alerts", "chartViewContext"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "datapointBackInSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled", "finishLoading", "updateActiveDatapoints", "updateAggregatedSliderDatapoint"] }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "component", type: i1.SelectComponent, selector: "c8y-select", inputs: ["placeholder", "items", "selected", "container", "multi", "canSelectWithSpace", "disabled", "autoClose", "insideClick", "required", "canDeselect", "name", "icon", "filterItems"], outputs: ["onSelect", "onDeselect", "onIconClick"] }, { kind: "directive", type: i1.SelectItemDirective, selector: "[c8ySelectItem]", inputs: ["c8ySelectItem", "c8ySelectItemLabel"] }, { kind: "directive", type: i1.SelectedItemsDirective, selector: "[c8ySelectedItems]" }, { 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: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.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: "ngmodule", type: BsDropdownModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "directive", type: i4.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "ngmodule", type: AlarmsModule }, { kind: "component", type: i9.AlarmsFilterComponent, selector: "c8y-alarms-filter", inputs: ["contextSourceId"], outputs: ["onFilterApplied"] }, { kind: "component", type: GlobalContextConnectorComponent, selector: "c8y-global-context-connector", inputs: ["controls", "config", "isLoading", "dashboardChild", "linked", "propagateAutoRefresh", "emitRefresh"], outputs: ["configChange", "refresh", "linkedChange"] }, { kind: "component", type: LocalControlsComponent, selector: "c8y-local-controls", inputs: ["controls", "displayMode", "config", "isLoading", "disabled", "propagateAutoRefresh", "emitRefresh", "dashboardChild"], outputs: ["configChange", "refresh"] }, { kind: "component", type: DatapointsExportSelectorComponent, selector: "c8y-datapoints-export-selector", inputs: ["displayMode", "containerClass", "exportConfig"], outputs: ["isOpen"] }, { kind: "component", type: WidgetActionWrapperComponent, selector: "c8y-widget-action" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: DatapointsGraphWidgetViewComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-datapoints-graph-widget-view', standalone: true, imports: [
                        A11yModule,
                        CommonModule$1,
                        ChartsComponent,
                        CoreModule,
                        TooltipModule,
                        BsDropdownModule,
                        PopoverModule,
                        AlarmsModule,
                        GlobalContextConnectorComponent,
                        LocalControlsComponent,
                        DatapointsExportSelectorComponent,
                        SelectComponent,
                        SelectItemDirective,
                        SelectedItemsDirective,
                        WidgetActionWrapperComponent
                    ], providers: [ChartEventsService, ChartAlarmsService, WidgetTimeContextDateRangeService], template: "@if (displayMode() === GLOBAL_CONTEXT_DISPLAY_MODE.DASHBOARD) {\n  <c8y-global-context-connector\n    [controls]=\"widgetControls()\"\n    [config]=\"contextConfig()\"\n    [isLoading]=\"isLoading$ | async\"\n    [dashboardChild]=\"getDashboardChild()\"\n    [linked]=\"isLinkedToGlobal()\"\n    [propagateAutoRefresh]=\"false\"\n    (configChange)=\"onContextChange($event)\"\n  ></c8y-global-context-connector>\n} @else {\n  <c8y-local-controls\n    [controls]=\"widgetControls()\"\n    [displayMode]=\"displayMode()\"\n    [config]=\"contextConfig()\"\n    [isLoading]=\"isLoading$ | async\"\n    [propagateAutoRefresh]=\"false\"\n    (configChange)=\"onContextChange($event)\"\n  ></c8y-local-controls>\n}\n\n<div\n  class=\"p-l-16 p-r-16\"\n  style=\"min-height: 34px\"\n>\n  <div class=\"d-flex gap-16 a-i-center\">\n    @if (hasAtLeastOneAlarmActive) {\n      <c8y-alarms-filter\n        class=\"d-contents form-group-sm min-width-0\"\n        (onFilterApplied)=\"filterSeverity($event)\"\n      ></c8y-alarms-filter>\n    }\n    @if (displayConfig?.datapoints.length > 0) {\n      <div class=\"d-flex a-i-center min-width-0\">\n        @if (\n          displayConfig.dataPointLegendDisplay === 'dropdown' ||\n          (displayConfig.dataPointLegendDisplay === 'auto' && totalLegendItems > 5)\n        ) {\n          <c8y-select\n            class=\"min-width-0 c8y-select-v2--sm\"\n            aria-label=\"{{ 'Select data points, alarms or events' | translate }}\"\n            [placeholder]=\"'Select data points, alarms or events' | translate\"\n            [multi]=\"true\"\n            [filterItems]=\"true\"\n            [(ngModel)]=\"selectedItems\"\n            (onSelect)=\"onItemSelected($event)\"\n            (onDeselect)=\"onItemDeselected($event)\"\n          >\n            @for (item of selectableItems; track item.value) {\n              <div\n                class=\"d-flex a-i-center gap-4\"\n                *c8ySelectItem=\"item.value; label: item.label\"\n              >\n                @if (\n                  !hasAtLeastOneDatapointActive &&\n                  item.value.type === 'DATAPOINT' &&\n                  item.value.original.__active\n                ) {\n                  <i\n                    class=\"text-warning m-r-4\"\n                    c8yIcon=\"exclamation-triangle\"\n                    [tooltip]=\"'At least 1 data point must be active.' | translate\"\n                    container=\"body\"\n                    data-cy=\"datapoint-warning-icon\"\n                    [adaptivePosition]=\"false\"\n                  ></i>\n                }\n                @if (item.value.type === 'DATAPOINT') {\n                  <span\n                    class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n                    [style.background-color]=\"item.value.original.color\"\n                  ></span>\n                }\n                @if (item.value.type === 'ALARM') {\n                  <span\n                    class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n                    [style.background-color]=\"item.value.original.color\"\n                  >\n                    <i\n                      class=\"stroked-icon\"\n                      c8yIcon=\"bell\"\n                    ></i>\n                  </span>\n                }\n                @if (item.value.type === 'EVENT') {\n                  <span\n                    class=\"circle-icon-wrapper a-s-start circle-icon-wrapper--small\"\n                    [ngStyle]=\"{ 'background-color': item.value.original.color }\"\n                  >\n                    <i\n                      class=\"stroked-icon\"\n                      c8yIcon=\"online1\"\n                    ></i>\n                  </span>\n                }\n                <span class=\"text-truncate d-col\">\n                  <small class=\"text-truncate\">{{ item.value.original.label }}</small>\n                  <span class=\"text-muted text-10\">{{ item.value.original.__target?.name }}</span>\n                </span>\n              </div>\n            }\n            <span\n              class=\"tag tag--info chip\"\n              title=\"{{ selectedItem.label }}\"\n              *c8ySelectedItems=\"let selectedItem\"\n            >\n              <button\n                class=\"btn btn-xs btn-clean text-10\"\n                title=\"{{ selectedItem.label }}\"\n                type=\"button\"\n                (click)=\"\n                  $event.preventDefault(); $event.stopPropagation(); onItemDeselected(selectedItem)\n                \"\n              >\n                <i c8yIcon=\"times\"></i>\n              </button>\n              @if (isLastActiveDatapoint(selectedItem)) {\n                <i\n                  class=\"text-warning a-s-start\"\n                  c8yIcon=\"exclamation-triangle\"\n                  [tooltip]=\"'At least 1 data point must be active.' | translate\"\n                  container=\"body\"\n                  data-cy=\"datapoint-warning-icon\"\n                  [adaptivePosition]=\"false\"\n                ></i>\n              }\n              @if (selectedItem.value.type === 'DATAPOINT') {\n                <span\n                  class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                  [style.background-color]=\"selectedItem.value?.original.color || ''\"\n                ></span>\n              }\n              @if (selectedItem.value?.type === 'ALARM') {\n                <span\n                  class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                  [style.background-color]=\"selectedItem.value?.original.color || ''\"\n                >\n                  <i\n                    class=\"stroked-icon\"\n                    c8yIcon=\"bell\"\n                  ></i>\n                </span>\n              }\n              @if (selectedItem.value?.type === 'EVENT') {\n                <span\n                  class=\"circle-icon-wrapper circle-icon-wrapper--small\"\n                  [ngStyle]=\"{\n                    'background-color': selectedItem.value?.original.color || ''\n                  }\"\n                >\n                  <i\n                    class=\"stroked-icon\"\n                    c8yIcon=\"online1\"\n                  ></i>\n                </span>\n              }\n            </span>\n          </c8y-select>\n        } @else {\n          <div class=\"inner-scroll\">\n            <div class=\"p-t-4 d-flex a-i-start gap-8\">\n              @for (datapoint of displayConfig.datapoints; track datapoint) {\n                @if (datapoint.retrievalError) {\n                  <i\n                    class=\"text-warning m-l-4\"\n                    c8yIcon=\"exclamation-triangle\"\n                    [tooltip]=\"'Data point no longer exists.' | translate\"\n                    container=\"body\"\n                    [adaptivePosition]=\"false\"\n                  ></i>\n                } @else {\n                  <div\n                    class=\"c8y-datapoint-pill pill--sm flex-no-shrink\"\n                    title=\"{{ datapoint.label }} - {{ datapoint.__target.name }}\"\n                    [ngClass]=\"{ active: datapoint.__active }\"\n                  >\n                    @if (!hasAtLeastOneDatapointActive && datapoint.__active) {\n                      <i\n                        class=\"text-warning m-l-4\"\n                        c8yIcon=\"exclamation-triangle\"\n                        [tooltip]=\"'At least 1 data point must be active.' | translate\"\n                        container=\"body\"\n                        data-cy=\"datapoint-warning-icon\"\n                        [adaptivePosition]=\"false\"\n                      ></i>\n                    }\n                    <button\n                      class=\"c8y-datapoint-pill__btn\"\n                      title=\"{{\n                        (datapoint.__active ? hideDatapointLabel : showDatapointLabel) | translate\n                      }} \"\n                      type=\"button\"\n                      data-cy=\"datapoint-toggle-visibility-btn\"\n                      (click)=\"toggleChart(datapoint)\"\n                    >\n                      <i\n                        class=\"icon-14\"\n                        [c8yIcon]=\"datapoint.__active ? 'eye text-primary' : 'eye-slash text-muted'\"\n                      ></i>\n                    </button>\n                    <div class=\"c8y-datapoint-pill__label c8y-datapoint-pill__btn\">\n                      <i\n                        class=\"m-r-4 icon-14\"\n                        c8yIcon=\"circle\"\n                        [ngStyle]=\"{\n                          color: datapoint.color\n                        }\"\n                      ></i>\n                      <span\n                        class=\"text-truncate\"\n                        [ngClass]=\"{ 'text-muted': !datapoint.__active }\"\n                      >\n                        <span class=\"text-truncate text-bold\">\n                          {{ datapoint.label }}\n                        </span>\n                        <small class=\"text-muted text-10\">\n                          {{ datapoint.__target.name }}\n                        </small>\n                      </span>\n                      @if (datapointsOutOfSync.get(datapoint)) {\n                        <i\n                          class=\"text-warning m-l-4\"\n                          c8yIcon=\"exclamation-triangle\"\n                          [tooltip]=\"\n                            'Measurements received for this data point may be out of sync.'\n                              | translate\n                          \"\n                          container=\"body\"\n                          [adaptivePosition]=\"false\"\n                        ></i>\n                      }\n                    </div>\n                  </div>\n                }\n              }\n\n              @for (alarm of alarms; track alarm) {\n                <div\n                  class=\"c8y-alarm-pill pill--sm flex-no-shrink\"\n                  title=\"{{ alarm.filters.type }} \"\n                >\n                  @if (displayConfig?.activeAlarmTypesOutOfRange?.includes(alarm.filters.type)) {\n                    <i\n                      class=\"text-warning m-l-4\"\n                      c8yIcon=\"exclamation-triangle\"\n                      [tooltip]=\"\n                        'Alarm of this type is currently active and outside of the selected time range'\n                          | translate\n                      \"\n                      container=\"body\"\n                      [adaptivePosition]=\"false\"\n                    ></i>\n                  }\n                  <button\n                    class=\"c8y-alarm-pill__btn\"\n                    title=\"{{ alarm.filters.type }} \"\n                    type=\"button\"\n                    (click)=\"toggleAlarmEventType(alarm)\"\n                  >\n                    <i\n                      class=\"icon-14\"\n                      [c8yIcon]=\"\n                        alarm.__hidden || !alarm.__active\n                          ? 'eye-slash text-muted'\n                          : 'eye text-primary'\n                      \"\n                    ></i>\n                  </button>\n                  <button\n                    class=\"c8y-alarm-pill__label c8y-alarm-pill__btn\"\n                    (click)=\"toggleMarkedArea(alarm)\"\n                    [ngClass]=\"{\n                      active:\n                        !isMarkedAreaEnabled && alarm.filters.type === enabledMarkedAreaAlarmType\n                    }\"\n                  >\n                    <span\n                      class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n                      [style.background-color]=\"alarm.color\"\n                    >\n                      <i\n                        class=\"stroked-icon\"\n                        c8yIcon=\"bell\"\n                      ></i>\n                    </span>\n                    <span\n                      class=\"text-truncate\"\n                      [ngClass]=\"{ 'text-muted': alarm.__hidden }\"\n                    >\n                      <span class=\"text-truncate text-bold\">\n                        {{ alarm.label || alarm.filters.type }}\n                      </span>\n                      <small class=\"text-muted text-10\">\n                        {{ alarm.__target.name }}\n                      </small>\n                    </span>\n                  </button>\n                </div>\n              }\n\n              @for (event of events; track event) {\n                <div\n                  class=\"c8y-event-pill pill--sm flex-no-shrink\"\n                  title=\"{{ event.filters.type }}\"\n                >\n                  <button\n                    class=\"c8y-event-pill__btn\"\n                    title=\"{{ event.filters.type }} \"\n                    type=\"button\"\n                    (click)=\"toggleAlarmEventType(event)\"\n                  >\n                    <i\n                      class=\"icon-14\"\n                      [c8yIcon]=\"\n                        event.__hidden || !event.__active\n                          ? 'eye-slash text-muted'\n                          : 'eye text-primary'\n                      \"\n                    ></i>\n                  </button>\n                  <div class=\"c8y-event-pill__label c8y-event-pill__btn\">\n                    <span\n                      class=\"circle-icon-wrapper circle-icon-wrapper--small m-r-4\"\n                      [ngStyle]=\"{ 'background-color': event.color }\"\n                    >\n                      <i\n                        class=\"stroked-icon\"\n                        c8yIcon=\"online1\"\n                      ></i>\n                    </span>\n                    <span\n                      class=\"text-truncate text-bold\"\n                      [ngClass]=\"{ 'text-muted': event.__hidden }\"\n                    >\n                      <span class=\"text-truncate\">\n                        {{ event.label || event.filters.type }}\n                      </span>\n                      <small class=\"text-muted text-10\">\n                        {{ event.__target.name }}\n                      </small>\n                    </span>\n                  </div>\n                </div>\n              }\n            </div>\n          </div>\n          <button\n            class=\"btn-help btn-help--sm m-r-8\"\n            [attr.aria-label]=\"'Help' | translate\"\n            [popover]=\"legendHelpTemplate\"\n            placement=\"left\"\n            triggers=\"focus\"\n            container=\"body\"\n            [adaptivePosition]=\"true\"\n          ></button>\n        }\n      </div>\n    }\n  </div>\n</div>\n\n@if (displayConfig !== null) {\n  <c8y-charts\n    #chart\n    [config]=\"displayConfig\"\n    [alerts]=\"alerts\"\n    [chartViewContext]=\"chartViewContext\"\n    (updateAlarmsAndEvents)=\"updateAlarmsAndEvents($event)\"\n    (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n    (datapointOutOfSync)=\"handleDatapointOutOfSync($event)\"\n    (datapointBackInSync)=\"handleDatapointBackInSync($event)\"\n    (finishLoading)=\"this.isLoading$.next($event)\"\n    (isMarkedAreaEnabled)=\"isMarkedAreaEnabled = $event\"\n  ></c8y-charts>\n}\n\n<ng-template #legendHelpTemplate>\n  <div [innerHTML]=\"legendHelp\"></div>\n</ng-template>\n\n<c8y-widget-action>\n  <c8y-datapoints-export-selector\n    [displayMode]=\"'icon-only'\"\n    [exportConfig]=\"exportConfig\"\n    [containerClass]=\"'d-contents'\"\n  ></c8y-datapoints-export-selector>\n  <button\n    class=\"btn btn-icon\"\n    [attr.aria-label]=\"'Save as image' | translate\"\n    tooltip=\"{{ 'Save as image' | translate }}\"\n    container=\"body\"\n    type=\"button\"\n    [delay]=\"500\"\n    (click)=\"chartComponent.saveAsImage()\"\n    [adaptivePosition]=\"false\"\n  >\n    <i\n      class=\"icon-14\"\n      c8yIcon=\"image-file-checked\"\n    ></i>\n  </button>\n</c8y-widget-action>\n" }]
        }], ctorParameters: () => [{ type: i1$1.TranslateService }, { type: i2$1.ContextDashboardComponent, decorators: [{
                    type: Optional
                }] }, { type: i3$1.WidgetConfigMigrationService }, { type: i1.WidgetTimeContextDateRangeService }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{
                type: Input
            }], chartComponent: [{
                type: ViewChild,
                args: [ChartsComponent]
            }] } });

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

export { DatapointsGraphWidgetConfigComponent, DatapointsGraphWidgetViewComponent };
//# sourceMappingURL=c8y-ngx-components-widgets-implementations-datapoints-graph.mjs.map
