UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

1,230 lines 83.3 kB
import * as i0 from '@angular/core';
import { Pipe, Injectable, inject, ViewChild, Input, Component, Optional, EventEmitter, forwardRef, Output } from '@angular/core';
import * as i1 from '@c8y/ngx-components';
import { ThemeSwitcherService, MeasurementRealtimeService, DatePipe, CommonModule, FormGroupComponent, MessagesComponent, FormsModule } from '@c8y/ngx-components';
import * as i1$2 from '@angular/common';
import { AsyncPipe, NgIf, NgFor, NgStyle, DecimalPipe } from '@angular/common';
import { of, BehaviorSubject, switchMap, tap, Subject, takeUntil, debounceTime } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import * as i2 from '@c8y/ngx-components/context-dashboard';
import { defaultWidgetIds } from '@c8y/ngx-components/widgets/definitions';
import * as i1$1 from 'ngx-echarts';
import { NgxEchartsModule, NGX_ECHARTS_CONFIG } from 'ngx-echarts';
import { gettext } from '@c8y/ngx-components/gettext';
import * as i1$3 from '@angular/forms';
import { NG_VALUE_ACCESSOR, Validators, NgForm, ControlContainer, ReactiveFormsModule } from '@angular/forms';
import * as i5 from '@c8y/ngx-components/datapoint-selector';
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
import { EditorComponent, MonacoEditorMarkerValidatorDirective } from '@c8y/ngx-components/editor';
import * as i4 from 'ngx-bootstrap/collapse';
import { CollapseModule } from 'ngx-bootstrap/collapse';

const INFO_GAUGE_COLORS = {
    GREEN: 'var(--c8y-brand-50)',
    YELLOW: 'var(--c8y-palette-status-warning)',
    RED: 'var(--c8y-palette-status-danger)'
};
class InfoGaugeCurrentMeasurementPipe {
    constructor(measurementRealtime, alert) {
        this.measurementRealtime = measurementRealtime;
        this.alert = alert;
    }
    transform(datapoint, calculateGauge) {
        return this.measurementRealtime
            .latestValueOfSpecificMeasurement$(datapoint.fragment, datapoint.series, datapoint.__target, 1, true)
            .pipe(map(m => {
            // in case measurement is not stored in DB when initially requested.
            if (!m) {
                return { value: Number.NaN, date: '', unit: datapoint.unit || '', notFound: true };
            }
            const measurementValue = m[datapoint.fragment][datapoint.series];
            const data = {
                value: measurementValue.value,
                unit: measurementValue.unit || datapoint.unit,
                date: m.time
            };
            if (!calculateGauge) {
                return data;
            }
            const gauge = this.calculateGauge(datapoint, measurementValue.value);
            return { ...data, ...gauge };
        }), catchError(e => {
            this.alert.addServerFailure(e);
            return of({ value: Number.NaN, date: '', unit: '' });
        }));
    }
    calculateGauge(datapoint, value) {
        const val = value;
        const min = Number(datapoint.min || 0);
        const max = Number(datapoint.max || 0);
        const yMin = Number(datapoint.yellowRangeMin);
        const yMax = Number(datapoint.yellowRangeMax);
        const rMin = Number(datapoint.redRangeMin);
        const rMax = Number(datapoint.redRangeMax);
        // Previously d3 was used for linear scale: d3.scale.linear().domain([min, max]).range([0, 100]);
        // wanted to avoid importing d3 just for this.
        const scale = (value1) => (value1 - min) / ((max - min) / 100);
        const strokeDashOffset = 125.75 + (377.25 - (scale(val) / 100) * 377.25);
        let color = INFO_GAUGE_COLORS.GREEN;
        if (Number.isFinite(yMin) && Number.isFinite(yMax)) {
            if (val >= yMin && val <= yMax) {
                color = INFO_GAUGE_COLORS.YELLOW;
            }
        }
        if (Number.isFinite(rMin) && Number.isFinite(rMax)) {
            if (val >= rMin && val <= rMax) {
                color = INFO_GAUGE_COLORS.RED;
            }
        }
        return { color, strokeDashOffset };
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InfoGaugeCurrentMeasurementPipe, deps: [{ token: i1.MeasurementRealtimeService }, { token: i1.AlertService }], target: i0.ɵɵFactoryTarget.Pipe }); }
    static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.15", ngImport: i0, type: InfoGaugeCurrentMeasurementPipe, isStandalone: true, name: "infoGaugeCurrentMeasurement" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InfoGaugeCurrentMeasurementPipe, decorators: [{
            type: Pipe,
            args: [{
                    name: 'infoGaugeCurrentMeasurement',
                    pure: true,
                    standalone: true
                }]
        }], ctorParameters: () => [{ type: i1.MeasurementRealtimeService }, { type: i1.AlertService }] });

const GAUGE_PRESET_NAMES = {
    DEFAULT: gettext('Default'),
    CUSTOM: gettext('Custom preset'),
    POINTER: gettext('Pointer'),
    PROGRESS_BAR: gettext('Progress bar'),
    PROGRESS_INDICATOR: gettext('Progress indicator'),
    GRADE_RATING: gettext('Grade rating')
};
const GAUGE_PRESETS = [
    {
        // General properties
        name: GAUGE_PRESET_NAMES.DEFAULT,
        id: 'default',
        radius: '90%',
        startAngle: 240,
        endAngle: 300,
        // Split properties
        splitNumber: 10,
        splitLineLengthRatio: 0.3,
        splitLineColor: '#fff',
        splitLineWidth: 4,
        splitLineDistanceRatio: -0.3,
        // Tick properties
        tickShow: true,
        tickDistanceRatio: -0.16,
        tickWidth: 2,
        tickColor: '#fff',
        tickLengthRatio: 0.16,
        // Axis properties
        axisLabelDistanceRatio: 0.25,
        axisLabelColor: 'black',
        axisLabelFontSizeMin: 8,
        axisLabelFontSizeRatio: 0.04,
        axisLabelFontSizeMax: 32,
        axisLineWidthRatio: 0.125,
        // Pointer properties
        showPointer: true,
        pointerColor: '#222',
        pointerStyle: 'triangle',
        pointerWidthRatio: 2,
        pointerLength: '55%',
        pointerOffset: 0,
        // Progress bar properties
        progressBar: false,
        progressBarColor: '#119d11',
        // Detail properties
        showDetail: false,
        showMarkPoint: true,
        // Typography & Anchor
        measurementValueFontRatio: 0.08,
        measurementValueFontMin: 16,
        measurementValueFontMax: 56,
        measurementValueColor: 'white',
        unitFontSize: 18,
        unitFontRatio: 0.045,
        unitFontMin: 14,
        unitFontMax: 40,
        unitColor: 'white',
        dateFontSize: 0.001,
        dateFontRatio: 0.03,
        dateFontMin: 10,
        dateFontMax: 16,
        dateColor: 'gray',
        anchor: {
            show: true,
            sizeRatio: 0.5,
            itemStyle: {
                color: '#222' // Color of the anchor
            }
        }
    },
    {
        // General properties
        name: GAUGE_PRESET_NAMES.POINTER,
        id: 'pointer',
        radius: '90%',
        startAngle: 240,
        endAngle: 300,
        // Split properties
        splitNumber: 10,
        splitLineLengthRatio: 1,
        splitLineColor: '#fff',
        splitLineWidth: 4,
        splitLineDistanceRatio: -1,
        // Tick properties
        tickShow: true,
        tickDistanceRatio: -1,
        tickWidth: 2,
        tickColor: '#fff',
        tickLengthRatio: 0.2666666667,
        // Axis properties
        axisLabelColor: '#212121',
        axisLabelFontSizeMin: 8,
        axisLabelFontSizeRatio: 0.04,
        axisLabelFontSizeMax: 32,
        axisLineWidthRatio: 0.075,
        axisLabelDistanceRatio: 1.1666666667,
        // Pointer properties
        showPointer: true,
        pointerStyle: 'default',
        pointerColor: 'black',
        pointerWidthRatio: 0.2666666667,
        pointerLength: '70%',
        pointerOffset: 5,
        // Progress bar properties
        progressBar: false,
        progressBarColor: '#119d11',
        // Detail properties
        showDetail: true,
        detailOffsetCenter: ['0%', '35%'],
        showMarkPoint: false,
        // Typography specs
        measurementValueFontRatio: 0.08,
        measurementValueFontMin: 16,
        measurementValueFontMax: 56,
        measurementValueColor: 'black',
        unitFontSize: 18,
        unitFontRatio: 0.045,
        unitFontMin: 8,
        unitFontMax: 40,
        unitColor: 'black',
        dateFontRatio: 0.03,
        dateFontMin: 10,
        dateFontMax: 16,
        dateColor: 'black'
    },
    {
        // General properties
        name: GAUGE_PRESET_NAMES.PROGRESS_BAR,
        id: 'progress-bar',
        radius: '85%',
        center: ['50%', '57%'],
        startAngle: 200,
        endAngle: -20,
        // Split properties
        splitNumber: 10,
        splitLineLengthRatio: 1,
        splitLineColor: '#fff',
        splitLineWidth: 3,
        splitLineDistanceRatio: -1,
        // Tick properties
        tickShow: false,
        // Axis properties
        axisLabelColor: '#212121',
        axisLabelFontSizeMin: 8,
        axisLabelFontSizeRatio: 0.04,
        axisLabelFontSizeMax: 32,
        axisLineWidthRatio: 0.075,
        axisLabelDistanceRatio: -0.8,
        // Pointer properties
        showPointer: false,
        // Progress bar properties
        progressBar: true,
        progressBarWidthRatio: 0.3333,
        progressBarRoundCap: false,
        progressBarColor: '#119d11',
        additionalGaugeColors: ['#FFAB91', '#FD7347'],
        // Detail properties
        showDetail: true,
        detailOffsetCenter: ['0%', '0%'],
        showMarkPoint: false,
        // Typography specs
        measurementValueFontRatio: 0.12,
        measurementValueFontMin: 16,
        measurementValueFontMax: 72,
        measurementValueColor: 'black',
        unitFontSize: 18,
        unitFontRatio: 0.085,
        unitFontMin: 10,
        unitFontMax: 40,
        unitColor: 'black',
        dateFontRatio: 0.03,
        dateFontMin: 10,
        dateFontMax: 16,
        dateColor: 'black'
    },
    {
        // General properties
        name: GAUGE_PRESET_NAMES.PROGRESS_INDICATOR,
        id: 'progress-indicator',
        radius: '85%',
        startAngle: 240,
        endAngle: 300,
        // Split line properties
        splitNumber: 4,
        splitLineLengthRatio: 1,
        splitLineColor: '#fff',
        splitLineWidth: 2,
        splitLineDistanceRatio: -1,
        // Tick properties
        tickShow: false,
        // Axis properties
        axisLabelColor: '#212121',
        axisLabelFontSizeMin: 7,
        axisLabelFontSizeRatio: 0.04,
        axisLabelFontSizeMax: 32,
        axisLineWidthRatio: 0.075,
        axisLabelDistanceRatio: -1,
        // Pointer properties
        showPointer: true,
        pointerStyle: 'default',
        pointerColor: 'black',
        pointerWidthRatio: 0.2,
        pointerLength: '100%',
        pointerOffset: 5,
        // Progress bar properties
        progressBar: true,
        progressBarWidthRatio: 0.3333,
        progressBarRoundCap: false,
        progressBarColor: '#119d11',
        // Detail properties
        showDetail: true,
        detailOffsetCenter: ['0%', '35%'],
        showMarkPoint: false,
        // Typography  & Anchor
        measurementValueFontRatio: 0.08,
        measurementValueFontMin: 12,
        measurementValueFontMax: 56,
        measurementValueColor: 'black',
        unitFontSize: 18,
        unitFontRatio: 0.045,
        unitFontMin: 10,
        unitFontMax: 40,
        unitColor: 'black',
        dateFontRatio: 0.03,
        dateFontMin: 10,
        dateFontMax: 16,
        dateColor: 'black',
        anchor: {
            show: true,
            showAbove: true,
            sizeRatio: 0.1,
            itemStyle: {
                borderWidth: 10
            }
        }
    },
    {
        // General properties
        name: GAUGE_PRESET_NAMES.GRADE_RATING,
        id: 'grade-rating',
        radius: '75%',
        startAngle: 180,
        endAngle: 360,
        center: ['50%', '65%'],
        // Split line properties
        splitNumber: 4,
        splitLineLengthRatio: 3,
        splitLineColor: 'auto',
        splitLineWidth: 6,
        splitLineDistanceRatio: -3,
        // Tick properties
        tickShow: true,
        tickDistanceRatio: -2,
        tickWidth: 2,
        tickColor: 'auto',
        tickLengthRatio: 2,
        // Axis properties
        axisLabelDistanceRatio: -6,
        axisLabelColor: 'auto',
        axisLabelFontSizeMin: 6,
        axisLabelFontSizeRatio: 0.04,
        axisLabelFontSizeMax: 32,
        axisLineWidthRatio: 0.02,
        // Pointer properties
        showPointer: true,
        pointerColor: 'black',
        pointerStyle: 'triangle',
        pointerWidthRatio: 2,
        pointerLength: '12%',
        pointerOffset: '-50%',
        // Progress bar properties
        progressBar: false,
        progressBarColor: '#119d11',
        // Detail properties
        showDetail: true,
        detailOffsetCenter: ['0%', '0%'],
        showMarkPoint: false,
        // Typography
        measurementValueFontRatio: 0.08,
        measurementValueFontMin: 16,
        measurementValueFontMax: 56,
        measurementValueColor: 'black',
        unitFontRatio: 0.045,
        unitFontMin: 8,
        unitFontMax: 40,
        unitColor: 'black',
        dateFontRatio: 0.03,
        dateFontMin: 10,
        dateFontMax: 16,
        dateColor: 'black'
    }
];

class RadialGaugeService {
    constructor(c8yDatePipe) {
        this.c8yDatePipe = c8yDatePipe;
        this.containerSize = 400;
    }
    setChart(chart) {
        this.chart = chart;
    }
    getChartOptions(gaugeOptions, activeDatapointGauge, selectedPresetId, gaugeOptionsColors, rangeColors, measurement, fractionSize) {
        const colorArray = this.getColorArray(activeDatapointGauge, rangeColors);
        return {
            series: [
                {
                    type: 'gauge',
                    radius: gaugeOptions?.radius || '90%',
                    center: gaugeOptions?.center || ['50%', '50%'],
                    startAngle: gaugeOptions?.startAngle || 240,
                    endAngle: gaugeOptions?.endAngle || 300,
                    min: activeDatapointGauge?.min || 0,
                    max: activeDatapointGauge?.max !== undefined && activeDatapointGauge?.max !== null
                        ? activeDatapointGauge.max
                        : 100,
                    // Split properties
                    splitNumber: gaugeOptions?.splitNumber || 10,
                    splitLine: {
                        distance: gaugeOptions?.splitLineDistanceRatio
                            ? this.containerSize *
                                gaugeOptions?.axisLineWidthRatio *
                                gaugeOptions?.splitLineDistanceRatio
                            : gaugeOptions?.splitLineDistance || -30,
                        length: gaugeOptions?.splitLineLengthRatio
                            ? this.containerSize *
                                gaugeOptions?.axisLineWidthRatio *
                                gaugeOptions?.splitLineLengthRatio
                            : gaugeOptions?.splitLineLength || 30,
                        lineStyle: {
                            color: selectedPresetId === 'custom' || selectedPresetId === 'grade-rating'
                                ? gaugeOptions?.splitLineColor
                                : gaugeOptionsColors?.splitLineColor || '#fff',
                            width: gaugeOptions?.splitLineWidth || 4
                        }
                    },
                    // Tick properties
                    axisTick: {
                        show: gaugeOptions?.tickShow || false,
                        distance: gaugeOptions?.tickDistanceRatio
                            ? this.containerSize *
                                gaugeOptions?.axisLineWidthRatio *
                                gaugeOptions?.tickDistanceRatio
                            : gaugeOptions?.tickDistance || -30,
                        length: gaugeOptions?.tickLengthRatio
                            ? this.containerSize *
                                gaugeOptions?.axisLineWidthRatio *
                                gaugeOptions?.tickLengthRatio
                            : gaugeOptions?.tickLength || 8,
                        lineStyle: {
                            color: selectedPresetId === 'custom' || selectedPresetId === 'grade-rating'
                                ? gaugeOptions.tickColor
                                : gaugeOptionsColors?.tickColor || '#fff',
                            width: gaugeOptions?.tickWidth || 2
                        }
                    },
                    // Axis properties
                    axisLine: {
                        lineStyle: {
                            width: gaugeOptions?.axisLineWidthRatio
                                ? this.containerSize * gaugeOptions?.axisLineWidthRatio
                                : gaugeOptions?.axisLineWidth || 30,
                            color: colorArray
                        }
                    },
                    axisLabel: {
                        color: selectedPresetId === 'custom' || selectedPresetId === 'grade-rating'
                            ? gaugeOptions.axisLabelColor
                            : gaugeOptionsColors?.axisLabelColor || 'inherit',
                        distance: gaugeOptions?.axisLabelDistanceRatio
                            ? this.containerSize *
                                gaugeOptions?.axisLineWidthRatio *
                                gaugeOptions?.axisLabelDistanceRatio
                            : gaugeOptions?.axisLabelDistance || 40,
                        fontSize: gaugeOptions?.axisLabelFontSizeRatio
                            ? this.clampRelative(gaugeOptions?.axisLabelFontSizeRatio, gaugeOptions?.axisLabelFontSizeMin, gaugeOptions?.axisLabelFontSizeMax)
                            : gaugeOptions?.axisLabelFontSize || 16,
                        fontWeight: 'bold',
                        fontFamily: gaugeOptionsColors?.fontFamily
                    },
                    // pointer properties
                    pointer: {
                        ...(gaugeOptions?.pointerStyle !== 'default' && {
                            icon: gaugeOptions?.pointerStyle
                        }),
                        show: gaugeOptions?.showPointer || false,
                        length: gaugeOptions?.pointerLengthRatio
                            ? gaugeOptions?.pointerLengthRatio *
                                (this.containerSize * gaugeOptions?.axisLineWidthRatio)
                            : gaugeOptions?.pointerLength || '65%',
                        width: gaugeOptions?.pointerWidthRatio
                            ? this.containerSize *
                                gaugeOptions?.axisLineWidthRatio *
                                gaugeOptions?.pointerWidthRatio
                            : gaugeOptions?.pointerWidth || 40,
                        offsetCenter: selectedPresetId === 'default'
                            ? [0, this.containerSize * gaugeOptions?.axisLineWidthRatio * -1]
                            : [0, gaugeOptions?.pointerOffset || -30],
                        itemStyle: {
                            color: selectedPresetId === 'custom'
                                ? gaugeOptions.pointerColor
                                : gaugeOptionsColors?.pointerColor || 'inherit'
                        }
                    },
                    // Progress bar properties
                    progress: {
                        show: gaugeOptions?.progressBar || false,
                        roundCap: gaugeOptions?.progressBarRoundCap || false,
                        width: gaugeOptions?.progressBarWidthRatio
                            ? this.containerSize *
                                gaugeOptions?.axisLineWidthRatio *
                                gaugeOptions?.progressBarWidthRatio
                            : gaugeOptions?.progressBarWidth || 18,
                        itemStyle: {
                            color: selectedPresetId === 'custom'
                                ? gaugeOptions.progressBarColor
                                : gaugeOptionsColors?.progressBarColor || 'inherit'
                        }
                    },
                    // Anchor properties
                    anchor: gaugeOptions?.anchor
                        ? {
                            ...gaugeOptions.anchor,
                            size: gaugeOptions?.anchor?.sizeRatio
                                ? this.containerSize * gaugeOptions?.anchor?.sizeRatio
                                : gaugeOptions?.anchor?.size || 45,
                            itemStyle: {
                                color: selectedPresetId === 'custom'
                                    ? gaugeOptions.pointerColor
                                    : gaugeOptionsColors?.pointerColor
                            }
                        }
                        : undefined,
                    // Detail properties
                    detail: {
                        show: gaugeOptions?.showDetail || false,
                        valueAnimation: true,
                        offsetCenter: gaugeOptions?.detailOffsetCenterYRatio
                            ? [0, gaugeOptions?.detailOffsetCenterYRatio * this.containerSize]
                            : gaugeOptions?.detailOffsetCenter || [0, 0],
                        formatter: () => {
                            const value = measurement?.value.toFixed(fractionSize) || 0;
                            const unit = activeDatapointGauge?.unit || measurement?.unit || '';
                            const date = new Date(measurement?.date);
                            const formattedDate = this.c8yDatePipe.transform(date);
                            return `{value|${value}}{unit|${unit}} \n {date|${formattedDate}} `;
                        },
                        color: 'inherit',
                        lineHeight: gaugeOptions?.measurementValueFontRatio
                            ? this.clampRelative(gaugeOptions?.measurementValueFontRatio * 0.9, gaugeOptions?.measurementValueFontSizeMin, gaugeOptions?.measurementValueFontSizeMax)
                            : gaugeOptions?.measurementValueFontSize || 32,
                        rich: {
                            value: {
                                fontSize: gaugeOptions?.measurementValueFontRatio
                                    ? this.clampRelative(fractionSize > 5 || measurement?.value > 9999
                                        ? gaugeOptions?.measurementValueFontRatio * 0.5
                                        : gaugeOptions?.measurementValueFontRatio, gaugeOptions?.measurementValueFontSizeMin, gaugeOptions?.measurementValueFontSizeMax)
                                    : gaugeOptions?.measurementValueFontSize || 32,
                                fontWeight: 'bolder',
                                fontFamily: gaugeOptionsColors?.fontFamily,
                                color: selectedPresetId === 'custom'
                                    ? gaugeOptions.measurementValueColor
                                    : gaugeOptionsColors?.measurementValueColor || '#777'
                            },
                            unit: {
                                fontSize: gaugeOptions?.unitFontRatio
                                    ? this.clampRelative(gaugeOptions?.unitFontRatio, gaugeOptions?.unitFontMin, gaugeOptions?.unitFontMax)
                                    : gaugeOptions?.unitFontSize || 20,
                                fontFamily: gaugeOptionsColors?.fontFamily,
                                color: selectedPresetId === 'custom'
                                    ? gaugeOptions?.unitColor
                                    : gaugeOptionsColors?.unitColor || '#999'
                            },
                            date: {
                                fontSize: gaugeOptions?.dateFontRatio
                                    ? this.clampRelative(gaugeOptions?.dateFontRatio, gaugeOptions?.dateFontSizeMin, gaugeOptions?.dateFontSizeMax)
                                    : gaugeOptions?.dateFontSize || 12,
                                fontFamily: gaugeOptionsColors?.fontFamily,
                                color: selectedPresetId === 'custom'
                                    ? gaugeOptions?.dateColor
                                    : gaugeOptionsColors?.dateColor || '#555'
                            }
                        }
                    },
                    markPoint: {
                        symbolSize: 0,
                        offsetCenter: gaugeOptions?.detailOffsetCenter || [0, 0],
                        data: [
                            {
                                x: '50%',
                                y: '50%',
                                label: {
                                    show: gaugeOptions?.showMarkPoint,
                                    formatter: () => {
                                        const value = measurement?.value.toFixed(fractionSize) || 0;
                                        const unit = activeDatapointGauge?.unit || measurement?.unit || '';
                                        const date = new Date(measurement?.date);
                                        const formattedDate = this.c8yDatePipe.transform(date);
                                        return `{value|${value}}{unit|${unit}} \n {date|${formattedDate}} `;
                                    },
                                    color: '#fff',
                                    align: 'center',
                                    rich: {
                                        value: {
                                            fontSize: gaugeOptions?.measurementValueFontRatio
                                                ? this.clampRelative(fractionSize > 5
                                                    ? gaugeOptions?.measurementValueFontRatio * 0.5
                                                    : gaugeOptions?.measurementValueFontRatio, fractionSize > 5
                                                    ? gaugeOptions.measurementValueFontMin * 0.5
                                                    : gaugeOptions?.measurementValueFontSizeMin, gaugeOptions?.measurementValueFontSizeMax)
                                                : gaugeOptions?.measurementValueFontSize || 32,
                                            fontFamily: gaugeOptionsColors?.fontFamily,
                                            fontWeight: 'bolder',
                                            color: gaugeOptionsColors?.knobFontColor || '#777'
                                        },
                                        unit: {
                                            fontSize: gaugeOptions?.unitFontRatio
                                                ? this.clampRelative(gaugeOptions?.unitFontRatio, gaugeOptions?.unitFontSizeMin, gaugeOptions?.unitFontSizeMax)
                                                : gaugeOptions?.unitFontSize || 20,
                                            fontFamily: gaugeOptionsColors?.fontFamily,
                                            color: gaugeOptionsColors?.knobFontColor || '#999'
                                        },
                                        date: {
                                            fontSize: gaugeOptions?.dateFontRatio
                                                ? this.clampRelative(gaugeOptions?.dateFontRatio, gaugeOptions?.dateFontSizeMin, gaugeOptions?.dateFontSizeMax)
                                                : gaugeOptions?.dateFontSize || 12,
                                            fontFamily: gaugeOptionsColors?.fontFamily,
                                            color: gaugeOptionsColors?.knobFontColor || '#555'
                                        }
                                    }
                                }
                            }
                        ]
                    },
                    data: [
                        {
                            value: 0 || measurement?.value
                        }
                    ]
                }
            ]
        };
    }
    updateRangeColors() {
        if (!this.chart) {
            return;
        }
        return {
            default: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-form-control-border-color-default'),
            yellow: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-palette-status-warning'),
            red: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-palette-status-danger')
        };
    }
    updateGaugeOptionsColors() {
        if (!this.chart) {
            return;
        }
        return {
            splitLineColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-background-default'),
            tickColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-background-default'),
            axisLabelColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
            pointerColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
            knobColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
            knobFontColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-background-default'),
            measurementValueColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
            unitColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-color-default'),
            dateColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-text-muted'),
            progressBarColor: getComputedStyle(this.chart.nativeElement).getPropertyValue('--c8y-root-component-brand-primary'),
            fontFamily: getComputedStyle(document.body).getPropertyValue('font-family')
        };
    }
    getColorArray(activeDatapointGauge, rangeColors) {
        const min = activeDatapointGauge?.min ?? 0;
        const max = activeDatapointGauge?.max ?? 100;
        const range = max - min;
        const yellowMin = activeDatapointGauge?.yellowRangeMin;
        const yellowMax = activeDatapointGauge?.yellowRangeMax;
        const redMin = activeDatapointGauge?.redRangeMin;
        const redMax = activeDatapointGauge?.redRangeMax;
        const ranges = [];
        // First add red range
        if (redMin != null && redMax != null && redMin < redMax) {
            ranges.push({ start: redMin, end: redMax, color: rangeColors.red });
        }
        // Then add yellow, but clip out any overlap with red
        if (yellowMin != null && yellowMax != null && yellowMin < yellowMax) {
            const redRange = ranges.find(r => r.color === rangeColors.red);
            if (!redRange ||
                yellowMax <= redRange.start || // yellow ends before red
                yellowMin >= redRange.end // yellow starts after red
            ) {
                // no overlap
                ranges.push({ start: yellowMin, end: yellowMax, color: rangeColors.yellow });
            }
            else {
                // partial overlap – split yellow into non-overlapping parts
                if (yellowMin < redRange.start) {
                    ranges.push({
                        start: yellowMin,
                        end: Math.min(yellowMax, redRange.start),
                        color: rangeColors.yellow
                    });
                }
                if (yellowMax > redRange.end) {
                    ranges.push({
                        start: Math.max(yellowMin, redRange.end),
                        end: yellowMax,
                        color: rangeColors.yellow
                    });
                }
            }
        }
        // Sort by start position
        ranges.sort((a, b) => a.start - b.start);
        // Build segments
        const segments = [];
        let current = min;
        for (const { start, end, color } of ranges) {
            if (start > current) {
                // Default fill before this range
                segments.push([(start - min) / range, rangeColors.default]);
            }
            // Start color
            segments.push([(start - min) / range, color]);
            // End color
            segments.push([(end - min) / range, color]);
            current = Math.max(current, end);
        }
        // Fill remaining with default
        if (current < max) {
            segments.push([(current - min) / range, rangeColors.default]);
        }
        if (segments.length === 0 || segments[segments.length - 1][0] < 1) {
            segments.push([1, rangeColors.default]);
        }
        return segments;
    }
    clampRelative(ratio, min, max) {
        const clampedValue = this.containerSize * ratio;
        if (clampedValue < min) {
            return min;
        }
        else if (clampedValue > max) {
            return max;
        }
        else {
            return clampedValue;
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadialGaugeService, deps: [{ token: i1.DatePipe }], target: i0.ɵɵFactoryTarget.Injectable }); }
    static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadialGaugeService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadialGaugeService, decorators: [{
            type: Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], ctorParameters: () => [{ type: i1.DatePipe }] });

class RadialGaugeViewComponent {
    constructor() {
        this.fractionSize = 2;
        this.selectedPresetId = '';
        this.rangeColors = { default: '#E8EBED', yellow: '#ff8800', red: '#d70f0f' };
        this.configChangedSubject = new BehaviorSubject(null);
        this.themeSwitcherService = inject(ThemeSwitcherService);
        this.radialGaugeService = inject(RadialGaugeService);
        this.chartOptions$ = this.configChangedSubject.pipe(switchMap(() => of(this.radialGaugeService.getChartOptions(this.gaugeOptions, this.activeDatapointGauge, this.selectedPresetId, this.gaugeOptionsColors, this.rangeColors, this.measurement, this.fractionSize))), tap(options => {
            if (this.echartsInstance) {
                this.echartsInstance.setOption(options, false, true);
            }
        }));
    }
    ngOnInit() {
        if (!this.gaugeOptions) {
            this.gaugeOptions = GAUGE_PRESETS[0];
        }
        this.themeSubscription = this.themeSwitcherService.currentlyAppliedTheme$.subscribe(() => {
            queueMicrotask(() => {
                this.radialGaugeService.setChart(this.chart);
                this.rangeColors = this.radialGaugeService.updateRangeColors();
                this.gaugeOptionsColors = this.radialGaugeService.updateGaugeOptionsColors();
                requestAnimationFrame(() => {
                    this.configChangedSubject.next();
                });
            });
        });
    }
    ngAfterViewInit() {
        this.resizeObserver = new ResizeObserver(entries => {
            for (const entry of entries) {
                if (entry.contentRect.width > 0 && entry.contentRect.height > 0) {
                    this.radialGaugeService.containerSize =
                        entry.contentRect.width >= entry.contentRect.height
                            ? entry.contentRect.height
                            : entry.contentRect.width;
                    this.configChangedSubject.next();
                }
            }
        });
        this.resizeObserver.observe(this.chart.nativeElement);
    }
    ngOnDestroy() {
        if (this.themeSubscription) {
            this.themeSubscription.unsubscribe();
        }
        if (this.resizeObserver) {
            this.resizeObserver.disconnect();
        }
    }
    ngOnChanges(changes) {
        if (changes.gaugeOptions || changes.measurement || changes.activeDatapointGauge) {
            this.configChangedSubject.next();
        }
    }
    onChartInit(ec) {
        this.echartsInstance = ec;
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadialGaugeViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: RadialGaugeViewComponent, isStandalone: true, selector: "c8y-radial-gauge", inputs: { activeDatapointGauge: "activeDatapointGauge", measurement: "measurement", fractionSize: "fractionSize", gaugeOptions: "gaugeOptions", selectedPresetId: "selectedPresetId" }, host: { classAttribute: "c8y-radial-gauge" }, providers: [
            MeasurementRealtimeService,
            RadialGaugeService,
            { provide: NGX_ECHARTS_CONFIG, useFactory: () => ({ echarts: () => import('echarts') }) }
        ], viewQueries: [{ propertyName: "chart", first: true, predicate: ["chart"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div\n  class=\"p-absolute fit-w fit-h\"\n  data-cy=\"c8y-radial-gauge--chart\"\n  #chart\n  echarts\n  [options]=\"chartOptions$ | async\"\n  (chartInit)=\"onChartInit($event)\"\n></div>\n", dependencies: [{ kind: "ngmodule", type: NgxEchartsModule }, { kind: "directive", type: i1$1.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: RadialGaugeViewComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-radial-gauge', host: { class: 'c8y-radial-gauge' }, providers: [
                        MeasurementRealtimeService,
                        RadialGaugeService,
                        { provide: NGX_ECHARTS_CONFIG, useFactory: () => ({ echarts: () => import('echarts') }) }
                    ], standalone: true, imports: [AsyncPipe, NgxEchartsModule], template: "<div\n  class=\"p-absolute fit-w fit-h\"\n  data-cy=\"c8y-radial-gauge--chart\"\n  #chart\n  echarts\n  [options]=\"chartOptions$ | async\"\n  (chartInit)=\"onChartInit($event)\"\n></div>\n" }]
        }], ctorParameters: () => [], propDecorators: { activeDatapointGauge: [{
                type: Input
            }], measurement: [{
                type: Input
            }], fractionSize: [{
                type: Input
            }], gaugeOptions: [{
                type: Input
            }], selectedPresetId: [{
                type: Input
            }], chart: [{
                type: ViewChild,
                args: ['chart', { static: false }]
            }] } });

class InfoGaugeWidgetViewComponent {
    constructor(dashboard, dynamicComponent) {
        this.dashboard = dashboard;
        this.dynamicComponent = dynamicComponent;
        this.activeDatapointLabels = [];
        this.fractionSize = '1.1-1';
    }
    ngOnInit() {
        if (this.config?.datapoints && !this.config.datapointsGauge) {
            this.config.datapointsGauge = this.config.datapoints;
        }
    }
    ngOnChanges() {
        if (this.config?.datapointsLabels && Array.isArray(this.config?.datapointsLabels)) {
            this.config.datapointsLabels.forEach(dp => this.assignContextFromContextDashboard(dp));
            this.activeDatapointLabels = this.config?.datapointsLabels.filter(dp => dp.__active);
        }
        if (this.config?.datapointsGauge && Array.isArray(this.config?.datapointsGauge)) {
            this.config.datapointsGauge.forEach(dp => this.assignContextFromContextDashboard(dp));
            this.activeDatapointGauge = this.config?.datapointsGauge.find(dp => dp.__active);
        }
        if (this.config?.datapoints &&
            Array.isArray(this.config?.datapoints) &&
            this.config?.datapoints.length > 0 &&
            !this.config?.datapointsGauge) {
            this.config.datapoints.forEach(dp => this.assignContextFromContextDashboard(dp));
            this.activeDatapointGauge = this.config?.datapoints.find(dp => dp.__active);
        }
        if (this.config &&
            typeof this.config.fractionSize === 'number' &&
            !Number.isNaN(this.config.fractionSize)) {
            this.fractionSize = `1.${this.config.fractionSize}-${this.config.fractionSize}`;
        }
        this.isInfoGauge = this.dynamicComponent?.componentId === defaultWidgetIds.INFO_GAUGE;
    }
    assignContextFromContextDashboard(datapoint) {
        if (!this.dashboard?.isDeviceTypeDashboard) {
            return;
        }
        const context = this.dashboard?.context;
        if (context?.id) {
            const { name, id } = context;
            datapoint.__target = { name, id };
        }
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InfoGaugeWidgetViewComponent, deps: [{ token: i2.ContextDashboardComponent, optional: true }, { token: i1.DynamicComponentComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: InfoGaugeWidgetViewComponent, isStandalone: true, selector: "c8y-info-gauge-widget-view", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [MeasurementRealtimeService], usesOnChanges: true, ngImport: i0, template: "<div\n  class=\"label-value-unit-gauge new-radial\"\n  *ngIf=\"isInfoGauge\"\n>\n  <div\n    class=\"gauge-legend\"\n    *ngIf=\"activeDatapointLabels?.length && isInfoGauge\"\n  >\n    <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n      <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n        <label\n          class=\"text-truncate\"\n          title=\"{{ dp.label }}\"\n        >\n          {{ dp.label }}\n        </label>\n        <h3\n          class=\"text-truncate\"\n          title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n          *ngIf=\"!measurement.notFound; else notFound\"\n        >\n          {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n        </h3>\n        <ng-template #notFound>\n          <h3>--</h3>\n        </ng-template>\n        <p class=\"text-muted m-b-8\">\n          <small>\n            <em>{{ measurement.date | c8yDate: 'short' }}</em>\n          </small>\n        </p>\n      </ng-container>\n    </ng-container>\n  </div>\n\n  <ng-container *ngIf=\"activeDatapointGauge && isInfoGauge\">\n    <div\n      class=\"gauge-svg\"\n      *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n    >\n      <svg\n        height=\"214px\"\n        width=\"214px\"\n        viewBox=\"0 0 214 214\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <desc>radial gauge</desc>\n        <g\n          id=\"scale\"\n          stroke=\"none\"\n          stroke-width=\"1\"\n          fill=\"none\"\n          fill-rule=\"evenodd\"\n          stroke-dasharray=\"1,5\"\n        >\n          <circle\n            id=\"Oval\"\n            stroke=\"#CACECE\"\n            stroke-width=\"7\"\n            cx=\"107\"\n            cy=\"107\"\n            r=\"103\"\n          ></circle>\n          <rect\n            id=\"mask\"\n            height=\"214\"\n            stroke=\"none\"\n            fill-rule=\"evenodd\"\n            x=\"0\"\n            y=\"0\"\n            width=\"214\"\n            transform=\"rotate(-45 290 182)\"\n          ></rect>\n        </g>\n        <path\n          class=\"track\"\n          d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n          transform=\"rotate(-135 107 107)\"\n        ></path>\n        <path\n          class=\"track-value\"\n          [ngStyle]=\"{\n            stroke: measurement.color,\n            'stroke-dashoffset': -measurement.strokeDashOffset\n          }\"\n          d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n          transform=\"rotate(-135 107 107)\"\n        ></path>\n        <foreignObject\n          class=\"d-flex a-i-center j-c-center\"\n          height=\"100%\"\n          width=\"100%\"\n          requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n        >\n          <div\n            class=\"d-flex d-col fit-h a-i-center j-c-center\"\n            style=\"padding: 3rem\"\n            xmlns=\"http://www.w3.org/1999/xhtml\"\n          >\n            <p\n              class=\"text-truncate text-center\"\n              title=\"{{ activeDatapointGauge.label }}\"\n            >\n              {{ activeDatapointGauge.label }}\n            </p>\n            <p\n              class=\"center-value text-truncate\"\n              title=\"{{ measurement.value | number: fractionSize }}\"\n              *ngIf=\"!measurement.notFound; else notFoundSVG\"\n            >\n              {{ measurement.value | number: fractionSize }}\n            </p>\n            <ng-template #notFoundSVG>\n              <p class=\"center-value\">--</p>\n            </ng-template>\n            <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n            <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n          </div>\n        </foreignObject>\n      </svg>\n    </div>\n  </ng-container>\n\n  <div class=\"clearfix\"></div>\n</div>\n<ng-container *ngIf=\"!isInfoGauge\">\n  <c8y-radial-gauge\n    *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n    [activeDatapointGauge]=\"activeDatapointGauge\"\n    [measurement]=\"measurement\"\n    [fractionSize]=\"config.fractionSize\"\n    [gaugeOptions]=\"config.gaugeOptions\"\n    [selectedPresetId]=\"config.selectedPresetId\"\n  ></c8y-radial-gauge>\n</ng-container>\n", dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: RadialGaugeViewComponent, selector: "c8y-radial-gauge", inputs: ["activeDatapointGauge", "measurement", "fractionSize", "gaugeOptions", "selectedPresetId"] }, { kind: "pipe", type: InfoGaugeCurrentMeasurementPipe, name: "infoGaugeCurrentMeasurement" }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: DecimalPipe, name: "number" }, { kind: "pipe", type: DatePipe, name: "c8yDate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InfoGaugeWidgetViewComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-info-gauge-widget-view', host: { class: 'd-contents' }, providers: [MeasurementRealtimeService], standalone: true, imports: [
                        NgIf,
                        NgFor,
                        NgStyle,
                        InfoGaugeCurrentMeasurementPipe,
                        AsyncPipe,
                        DecimalPipe,
                        DatePipe,
                        RadialGaugeViewComponent
                    ], template: "<div\n  class=\"label-value-unit-gauge new-radial\"\n  *ngIf=\"isInfoGauge\"\n>\n  <div\n    class=\"gauge-legend\"\n    *ngIf=\"activeDatapointLabels?.length && isInfoGauge\"\n  >\n    <ng-container *ngFor=\"let dp of activeDatapointLabels\">\n      <ng-container *ngIf=\"dp | infoGaugeCurrentMeasurement | async as measurement\">\n        <label\n          class=\"text-truncate\"\n          title=\"{{ dp.label }}\"\n        >\n          {{ dp.label }}\n        </label>\n        <h3\n          class=\"text-truncate\"\n          title=\"{{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\"\n          *ngIf=\"!measurement.notFound; else notFound\"\n        >\n          {{ measurement.value | number: fractionSize }} {{ dp.unit || measurement.unit }}\n        </h3>\n        <ng-template #notFound>\n          <h3>--</h3>\n        </ng-template>\n        <p class=\"text-muted m-b-8\">\n          <small>\n            <em>{{ measurement.date | c8yDate: 'short' }}</em>\n          </small>\n        </p>\n      </ng-container>\n    </ng-container>\n  </div>\n\n  <ng-container *ngIf=\"activeDatapointGauge && isInfoGauge\">\n    <div\n      class=\"gauge-svg\"\n      *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement: true | async as measurement\"\n    >\n      <svg\n        height=\"214px\"\n        width=\"214px\"\n        viewBox=\"0 0 214 214\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n      >\n        <desc>radial gauge</desc>\n        <g\n          id=\"scale\"\n          stroke=\"none\"\n          stroke-width=\"1\"\n          fill=\"none\"\n          fill-rule=\"evenodd\"\n          stroke-dasharray=\"1,5\"\n        >\n          <circle\n            id=\"Oval\"\n            stroke=\"#CACECE\"\n            stroke-width=\"7\"\n            cx=\"107\"\n            cy=\"107\"\n            r=\"103\"\n          ></circle>\n          <rect\n            id=\"mask\"\n            height=\"214\"\n            stroke=\"none\"\n            fill-rule=\"evenodd\"\n            x=\"0\"\n            y=\"0\"\n            width=\"214\"\n            transform=\"rotate(-45 290 182)\"\n          ></rect>\n        </g>\n        <path\n          class=\"track\"\n          d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n          transform=\"rotate(-135 107 107)\"\n        ></path>\n        <path\n          class=\"track-value\"\n          [ngStyle]=\"{\n            stroke: measurement.color,\n            'stroke-dashoffset': -measurement.strokeDashOffset\n          }\"\n          d=\"M 107 27 a 80 80 0 1 0.1 0 Z\"\n          transform=\"rotate(-135 107 107)\"\n        ></path>\n        <foreignObject\n          class=\"d-flex a-i-center j-c-center\"\n          height=\"100%\"\n          width=\"100%\"\n          requiredFeatures=\"http://www.w3.org/TR/SVG11/feature#Extensibility\"\n        >\n          <div\n            class=\"d-flex d-col fit-h a-i-center j-c-center\"\n            style=\"padding: 3rem\"\n            xmlns=\"http://www.w3.org/1999/xhtml\"\n          >\n            <p\n              class=\"text-truncate text-center\"\n              title=\"{{ activeDatapointGauge.label }}\"\n            >\n              {{ activeDatapointGauge.label }}\n            </p>\n            <p\n              class=\"center-value text-truncate\"\n              title=\"{{ measurement.value | number: fractionSize }}\"\n              *ngIf=\"!measurement.notFound; else notFoundSVG\"\n            >\n              {{ measurement.value | number: fractionSize }}\n            </p>\n            <ng-template #notFoundSVG>\n              <p class=\"center-value\">--</p>\n            </ng-template>\n            <p class=\"center-unit strong\">{{ activeDatapointGauge.unit || measurement.unit }}</p>\n            <p class=\"center-date-time\">{{ measurement.date | c8yDate: 'short' }}</p>\n          </div>\n        </foreignObject>\n      </svg>\n    </div>\n  </ng-container>\n\n  <div class=\"clearfix\"></div>\n</div>\n<ng-container *ngIf=\"!isInfoGauge\">\n  <c8y-radial-gauge\n    *ngIf=\"activeDatapointGauge | infoGaugeCurrentMeasurement | async as measurement\"\n    [activeDatapointGauge]=\"activeDatapointGauge\"\n    [measurement]=\"measurement\"\n    [fractionSize]=\"config.fractionSize\"\n    [gaugeOptions]=\"config.gaugeOptions\"\n    [selectedPresetId]=\"config.selectedPresetId\"\n  ></c8y-radial-gauge>\n</ng-container>\n" }]
        }], ctorParameters: () => [{ type: i2.ContextDashboardComponent, decorators: [{
                    type: Optional
                }] }, { type: i1.DynamicComponentComponent, decorators: [{
                    type: Optional
                }] }], propDecorators: { config: [{
                type: Input
            }] } });

class PresetPreviewComponent {
    constructor() {
        this.onPresetChange = new EventEmitter();
        this.measurement = {
            value: Math.floor(Math.random() * 9) + 1,
            unit: 'ºC',
            date: '2025-04-22T20:07:49.354Z'
        };
        this.activeDatapointGauge = {
            fragment: 'c8y_Kpi',
            series: 'preview',
            unit: 'ºC',
            min: 0,
            max: 10,
            yellowRangeMax: 8,
            yellowRangeMin: 5,
            redRangeMin: 8,
            redRangeMax: 10
        };
        this.selectedPresetId = null;
    }
    writeValue(value) {
        this.selectedPresetId = value;
    }
    registerOnChange(fn) {
        this.onChange = fn;
    }
    registerOnTouched(fn) {
        this.onTouched = fn;
    }
    emitPresetChange(presetId) {
        this.selectedPresetId = presetId;
        this.onChange(presetId);
        this.onTouched();
        this.onPresetChange.emit(presetId);
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PresetPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.15", type: PresetPreviewComponent, isStandalone: true, selector: "c8y-preset-preview", inputs: { ALL_GAUGE_PRESETS: "ALL_GAUGE_PRESETS" }, outputs: { onPresetChange: "onPresetChange" }, providers: [
            {
                provide: NG_VALUE_ACCESSOR,
                useExisting: forwardRef(() => PresetPreviewComponent),
                multi: true
            }
        ], ngImport: i0, template: "<div class=\"d-grid grid__col--4-4-4 gap-4\">\n  <button\n    class=\"c8y-radial-gauge__preset preset-{{ preset.id }}\"\n    [class.selected]=\"preset.id === selectedPresetId\"\n    [attr.aria-label]=\"preset.name | translate\"\n    type=\"button\"\n    *ngFor=\"let preset of ALL_GAUGE_PRESETS\"\n    (click)=\"emitPresetChange(preset.id)\"\n  >\n    <c8y-radial-gauge\n      class=\"c8y-radial-gauge--square\"\n      *ngIf=\"preset.id !== 'custom'\"\n      [activeDatapointGauge]=\"activeDatapointGauge\"\n      [measurement]=\"measurement\"\n      [fractionSize]=\"2\"\n      [selectedPresetId]=\"preset.id\"\n      [gaugeOptions]=\"preset\"\n    ></c8y-radial-gauge>\n    <span>{{ preset.name | translate }}</span>\n  </button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RadialGaugeViewComponent, selector: "c8y-radial-gauge", inputs: ["activeDatapointGauge", "measurement", "fractionSize", "gaugeOptions", "selectedPresetId"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: PresetPreviewComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-preset-preview', standalone: true, imports: [CommonModule, RadialGaugeViewComponent], providers: [
                        {
                            provide: NG_VALUE_ACCESSOR,
                            useExisting: forwardRef(() => PresetPreviewComponent),
                            multi: true
                        }
                    ], template: "<div class=\"d-grid grid__col--4-4-4 gap-4\">\n  <button\n    class=\"c8y-radial-gauge__preset preset-{{ preset.id }}\"\n    [class.selected]=\"preset.id === selectedPresetId\"\n    [attr.aria-label]=\"preset.name | translate\"\n    type=\"button\"\n    *ngFor=\"let preset of ALL_GAUGE_PRESETS\"\n    (click)=\"emitPresetChange(preset.id)\"\n  >\n    <c8y-radial-gauge\n      class=\"c8y-radial-gauge--square\"\n      *ngIf=\"preset.id !== 'custom'\"\n      [activeDatapointGauge]=\"activeDatapointGauge\"\n      [measurement]=\"measurement\"\n      [fractionSize]=\"2\"\n      [selectedPresetId]=\"preset.id\"\n      [gaugeOptions]=\"preset\"\n    ></c8y-radial-gauge>\n    <span>{{ preset.name | translate }}</span>\n  </button>\n</div>\n" }]
        }], propDecorators: { ALL_GAUGE_PRESETS: [{
                type: Input
            }], onPresetChange: [{
                type: Output
            }] } });

function ensureAtLeastOneDatapointSelectedAndActive(datapointListAttributes) {
    return (control) => {
        const formValue = control.value;
        for (const listAttributeName of datapointListAttributes) {
            const valueForList = formValue[listAttributeName];
            if (!valueForList || !Array.isArray(valueForList)) {
                continue;
            }
            if (valueForList.find(dp => dp.__active)) {
                return null;
            }
        }
        return { noActiveDatapoint: true };
    };
}
class InfoGaugeWidgetConfigComponent {
    set previewMapSet(template) {
        if (template) {
            this.widgetConfigService.setPreview(template);
            return;
        }
        this.widgetConfigService.setPreview(null);
    }
    constructor(formBuilder, form, widgetConfig, widgetConfigService, dynamicComponent) {
        this.formBuilder = formBuilder;
        this.form = form;
        this.widgetConfig = widgetConfig;
        this.widgetConfigService = widgetConfigService;
        this.dynamicComponent = dynamicComponent;
        this.datapointSelectionConfig = {};
        this.defaultFormOptions = {
            showRedRange: true,
            showYellowRange: true,
            showRange: true,
            selectableChartRenderTypes: []
        };
        this.showAdvancedOptions = false;
        this.gaugeOptionsString = '';
        this.showAdvancedOptionsLabel = gettext('Show advanced options');
        this.hideAdvancedOptionsLabel = gettext('Hide advanced options');
        this.ALL_GAUGE_PRESETS = [...GAUGE_PRESETS];
        this.limits = {
            numberOfDecimalPlacesMax: 10,
            numberOfDecimalPlacesMin: 0
        };
        this.GAUGE_PRESETS = GAUGE_PRESETS;
        this.destroy$ = new Subject();
        this.jsonChange$ = new Subject();
    }
    onBeforeSave(config) {
        if (this.formGroup.valid) {
            Object.assign(config, this.formGroup.value);
            Object.assign(config, {
                gaugeOptions: this.gaugeOptions,
                selectedPresetId: this.isInfoGauge ? null : this.getPresetId(this.gaugeOptions)
            });
            return true;
        }
        return false;
    }
    ngOnInit() {
        if (this.widgetConfig.context?.id) {
            this.datapointSelectionConfig.contextAsset = this.widgetConfig?.context;
        }
        this.initForm();
        if (this.config?.datapointsLabels) {
            this.formGroup.patchValue({ datapointsLabels: this.config.datapointsLabels });
        }
        if (this.config?.datapointsGauge) {
            this.formGroup.patchValue({ datapointsGauge: this.config.datapointsGauge });
        }
        if (typeof this.config?.fractionSize === 'number' && !Number.isNaN(this.config?.fractionSize)) {
            this.formGroup.patchValue({ fractionSize: this.config.fractionSize });
        }
        this.isInfoGauge = this.dynamicComponent?.componentId === defaultWidgetIds.INFO_GAUGE;
        this.previewConfig = {
            ...this.config,
            fractionSize: this.config?.fractionSize ?? 2,
            datapointsGauge: this.config?.datapointsGauge ?? [],
            datapointsLabels: this.config?.datapointsLabels ?? []
        };
        const isRadialGauge = !this.isInfoGauge;
        if (isRadialGauge) {
            this.setupRadialGauge();
        }
        this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => {
            if (value.datapointsGauge) {
                this.activeDatapointGauge = value.datapointsGauge.find(dp => dp.__active);
            }
            if (value.datapointsLabels) {
                this.activeDatapointLabel = value.datapointsLabels.find(dp => dp.__active);
            }
            // this.previewConfig = { ...this.previewConfig, gaugeOptions: this.gaugeOptions };
            this.previewConfig = {
                ...this.previewConfig,
                ...value,
                selectedPresetId: value.gaugePresetId,
                gaugeOptions: this.gaugeOptions
            };
        });
        this.jsonChange$
            .pipe(takeUntil(this.destroy$), debounceTime(500))
            .subscribe(value => this.processJSONChange(value));
    }
    ngOnDestroy() {
        this.destroy$.next();
        this.destroy$.complete();
        this.jsonChange$.complete();
    }
    onRadioPresetChange(presetId) {
        // Find the selected preset
        const selectedPreset = this.ALL_GAUGE_PRESETS.find(preset => preset.id === presetId);
        if (selectedPreset) {
            this.gaugeOptions = { ...selectedPreset }; // Update gaugeOptions with the selected preset
            this.gaugeOptionsString = JSON.stringify(this.gaugeOptions, null, 2);
            // If the selected preset is not custom, hide advanced options
            if (selectedPreset.id !== 'custom') {
                this.showAdvancedOptions = false;
            }
            this.previewConfig = {
                ...this.previewConfig,
                selectedPresetId: selectedPreset.id,
                gaugeOptions: this.gaugeOptions
            };
            // Update the form control value
            this.formGroup.patchValue({ gaugePresetId: selectedPreset.id });
        }
    }
    async assignSchema() {
        const { schema } = await import('c8y-schema-loader?interfaceName=GaugeOptions!@c8y/ngx-components/widgets/implementations/info-gauge');
        this.editorComponent.monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
            validate: true,
            schemas: [
                {
                    uri: 'gauge-schema.json',
                    schema: schema,
                    fileMatch: ['*']
                }
            ],
            enableSchemaRequest: false,
            allowComments: false
        });
    }
    gaugeJSONChange(value) {
        this.jsonChange$.next(value);
    }
    trackByFn(_index, item) {
        return item.id;
    }
    processJSONChange(value) {
        try {
            const parsedOptions = JSON.parse(value);
            // Check if the parsed options match any existing preset
            const matchingPreset = this.GAUGE_PRESETS.find(preset => JSON.stringify(preset) === JSON.stringify(parsedOptions));
            if (matchingPreset) {
                this.formGroup.patchValue({ gaugePresetId: matchingPreset.id });
            }
            else {
                this.gaugeOptions = parsedOptions;
                this.gaugeOptions.name = GAUGE_PRESET_NAMES.CUSTOM;
                this.gaugeOptions.id = 'custom';
                const customPresetExists = this.ALL_GAUGE_PRESETS.some(preset => preset.id === 'custom');
                if (!customPresetExists) {
                    this.ALL_GAUGE_PRESETS = [...this.ALL_GAUGE_PRESETS, this.gaugeOptions];
                }
                else {
                    this.ALL_GAUGE_PRESETS = this.ALL_GAUGE_PRESETS.map(preset => preset.id === 'custom' ? this.gaugeOptions : preset);
                }
                this.formGroup.patchValue({ gaugePresetId: 'custom' });
                this.previewConfig = {
                    ...this.previewConfig,
                    selectedPresetId: 'custom',
                    gaugeOptions: this.gaugeOptions
                };
            }
        }
        catch (error) {
            console.error('Invalid JSON:', error);
        }
    }
    getPresetId(gaugeOptions) {
        const matchingPreset = this.GAUGE_PRESETS.find(preset => preset.id === gaugeOptions.id);
        return matchingPreset ? matchingPreset.id : 'custom';
    }
    setupRadialGauge() {
        if (this.config.datapoints && !this.config.datapointsGauge) {
            this.config.datapointsGauge = this.config.datapoints;
        }
        this.gaugeOptions = this.config.gaugeOptions || { ...this.GAUGE_PRESETS[0] };
        if (this.config.selectedPresetId === 'custom') {
            this.gaugeOptions.name = GAUGE_PRESET_NAMES.CUSTOM;
            this.gaugeOptions.id = 'custom';
            this.previewConfig = {
                ...this.previewConfig,
                selectedPresetId: 'custom',
                gaugeOptions: this.gaugeOptions
            };
            this.ALL_GAUGE_PRESETS = [...this.GAUGE_PRESETS, this.config.gaugeOptions];
            this.formGroup.patchValue({ gaugePresetId: 'custom' });
        }
        this.gaugeOptionsString = JSON.stringify(this.gaugeOptions, null, 2);
    }
    initForm() {
        this.formGroup = this.createForm();
        this.form.form.addControl('config', this.formGroup);
        this.formGroup.patchValue(this.config);
    }
    createForm() {
        return this.formBuilder.group({
            fractionSize: [
                2,
                [
                    Validators.required,
                    Validators.min(this.limits.numberOfDecimalPlacesMin),
                    Validators.max(this.limits.numberOfDecimalPlacesMax)
                ]
            ],
            datapointsLabels: this.formBuilder.control(new Array(), []),
            datapointsGauge: this.formBuilder.control(new Array(), []),
            gaugePresetId: [this.config.selectedPresetId || 'default']
        }, {
            validators: [
                ensureAtLeastOneDatapointSelectedAndActive(['datapointsLabels', 'datapointsGauge'])
            ]
        });
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InfoGaugeWidgetConfigComponent, deps: [{ token: i1$3.FormBuilder }, { token: i1$3.NgForm }, { token: i2.WidgetConfigComponent }, { token: i2.WidgetConfigService }, { token: i1.DynamicComponentComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.15", type: InfoGaugeWidgetConfigComponent, isStandalone: true, selector: "c8y-info-gauge-widget-config", inputs: { config: "config" }, providers: [MeasurementRealtimeService], viewQueries: [{ propertyName: "editorComponent", first: true, predicate: EditorComponent, descendants: true }, { propertyName: "previewMapSet", first: true, predicate: ["gaugePreview"], descendants: true }], ngImport: i0, template: "<form\n  class=\"fit-h\"\n  [formGroup]=\"formGroup\"\n>\n  @if (isInfoGauge) {\n    <div class=\"m-l-16 m-r-16\">\n      <c8y-form-group class=\"p-t-8\">\n        <label translate>Decimal places</label>\n        <input\n          class=\"form-control\"\n          name=\"fractionSize\"\n          type=\"number\"\n          formControlName=\"fractionSize\"\n          step=\"1\"\n        />\n        <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n      </c8y-form-group>\n      @if (formGroup.errors?.noActiveDatapoint) {\n        <div\n          class=\"alert alert-info\"\n          role=\"alert\"\n          translate\n        >\n          At least one data point for the labels or the gauge needs to be selected.\n        </div>\n      }\n      <c8y-datapoint-selection-list\n        class=\"bg-inherit separator-top p-t-16 d-block\"\n        listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n        name=\"datapoints\"\n        [defaultFormOptions]=\"defaultFormOptions\"\n        [config]=\"datapointSelectionConfig\"\n        [minActiveCount]=\"0\"\n        formControlName=\"datapointsLabels\"\n      ></c8y-datapoint-selection-list>\n\n      <c8y-datapoint-selection-list\n        class=\"bg-inherit separator-top p-t-16 d-block\"\n        listTitle=\"{{ 'Gauge`display`' | translate }}\"\n        name=\"datapoints\"\n        [defaultFormOptions]=\"defaultFormOptions\"\n        [config]=\"datapointSelectionConfig\"\n        [minActiveCount]=\"0\"\n        [maxActiveCount]=\"1\"\n        formControlName=\"datapointsGauge\"\n      ></c8y-datapoint-selection-list>\n    </div>\n  } @else {\n    <c8y-datapoint-selection-list\n      class=\"bg-inherit d-block\"\n      listTitle=\"{{ 'Data points`display`' | translate }}\"\n      name=\"datapoints\"\n      [defaultFormOptions]=\"defaultFormOptions\"\n      [config]=\"datapointSelectionConfig\"\n      [minActiveCount]=\"0\"\n      [maxActiveCount]=\"1\"\n      formControlName=\"datapointsGauge\"\n    ></c8y-datapoint-selection-list>\n\n    <c8y-form-group class=\"p-t-8 p-r-16 p-l-16\">\n      <label translate>Decimal places</label>\n      <input\n        class=\"form-control\"\n        name=\"fractionSize\"\n        type=\"number\"\n        formControlName=\"fractionSize\"\n        step=\"1\"\n      />\n      <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n    </c8y-form-group>\n\n    <div class=\"form-group p-r-16 p-l-16 m-b-0\">\n      <legend>\n        {{ 'Presets' | translate }}\n      </legend>\n      <c8y-preset-preview\n        formControlName=\"gaugePresetId\"\n        [ALL_GAUGE_PRESETS]=\"ALL_GAUGE_PRESETS\"\n        (onPresetChange)=\"onRadioPresetChange($event)\"\n      ></c8y-preset-preview>\n    </div>\n\n    <div class=\"p-16\">\n      <button\n        class=\"btn btn-default\"\n        aria-controls=\"advancedCollapse\"\n        [attr.aria-expanded]=\"showAdvancedOptions\"\n        type=\"button\"\n        (click)=\"showAdvancedOptions = !showAdvancedOptions\"\n      >\n        {{ showAdvancedOptions ? hideAdvancedOptionsLabel : showAdvancedOptionsLabel }}\n      </button>\n    </div>\n\n    <div\n      class=\"collapse\"\n      id=\"advancedCollapse\"\n      [collapse]=\"!showAdvancedOptions\"\n      [isAnimated]=\"true\"\n    >\n      <div\n        class=\"fit-h\"\n        style=\"min-height: 400px\"\n      >\n        <c8y-editor\n          [ngModel]=\"gaugeOptionsString\"\n          (ngModelChange)=\"gaugeJSONChange($event)\"\n          (editorInit)=\"assignSchema()\"\n          [ngModelOptions]=\"{ standalone: true }\"\n          monacoEditorMarkerValidator\n        ></c8y-editor>\n      </div>\n    </div>\n  }\n</form>\n\n<ng-template #gaugePreview>\n  @if (\n    (this.formGroup.value.datapointsGauge?.length > 0 && activeDatapointGauge) ||\n    (this.formGroup.value.datapointsLabels?.length > 0 && activeDatapointLabel)\n  ) {\n    <div style=\"height: 300px\">\n      <c8y-info-gauge-widget-view [config]=\"previewConfig\"></c8y-info-gauge-widget-view>\n    </div>\n  } @else {\n    <div class=\"d-col a-i-start j-c-center\">\n      <c8y-ui-empty-state\n        [icon]=\"'c8y-data-points'\"\n        [title]=\"'No data points selected' | translate\"\n        [subtitle]=\"'Select data point to render content' | translate\"\n        [horizontal]=\"false\"\n        data-cy=\"info-gauge--empty-state-no-data-point-selected\"\n      >\n        <p c8y-guide-docs>\n          <small translate>\n            Find out more in the\n            <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#info-gauge\">user documentation</a>\n            .\n          </small>\n        </p>\n      </c8y-ui-empty-state>\n    </div>\n  }\n</ng-template>\n", dependencies: [{ kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "component", type: MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "ngmodule", type: CommonModule }, { kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "ngmodule", type: CollapseModule }, { kind: "directive", type: i4.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: EditorComponent, selector: "c8y-editor", inputs: ["editorOptions", "theme"], outputs: ["editorInit"] }, { kind: "directive", type: MonacoEditorMarkerValidatorDirective, selector: "c8y-editor [monacoEditorMarkerValidator]" }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i5.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "component", type: PresetPreviewComponent, selector: "c8y-preset-preview", inputs: ["ALL_GAUGE_PRESETS"], outputs: ["onPresetChange"] }, { kind: "component", type: InfoGaugeWidgetViewComponent, selector: "c8y-info-gauge-widget-view", inputs: ["config"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.15", ngImport: i0, type: InfoGaugeWidgetConfigComponent, decorators: [{
            type: Component,
            args: [{ selector: 'c8y-info-gauge-widget-config', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], providers: [MeasurementRealtimeService], standalone: true, imports: [
                        FormGroupComponent,
                        MessagesComponent,
                        CommonModule,
                        FormsModule,
                        CollapseModule,
                        ReactiveFormsModule,
                        EditorComponent,
                        MonacoEditorMarkerValidatorDirective,
                        DatapointSelectorModule,
                        PresetPreviewComponent,
                        InfoGaugeWidgetViewComponent
                    ], template: "<form\n  class=\"fit-h\"\n  [formGroup]=\"formGroup\"\n>\n  @if (isInfoGauge) {\n    <div class=\"m-l-16 m-r-16\">\n      <c8y-form-group class=\"p-t-8\">\n        <label translate>Decimal places</label>\n        <input\n          class=\"form-control\"\n          name=\"fractionSize\"\n          type=\"number\"\n          formControlName=\"fractionSize\"\n          step=\"1\"\n        />\n        <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n      </c8y-form-group>\n      @if (formGroup.errors?.noActiveDatapoint) {\n        <div\n          class=\"alert alert-info\"\n          role=\"alert\"\n          translate\n        >\n          At least one data point for the labels or the gauge needs to be selected.\n        </div>\n      }\n      <c8y-datapoint-selection-list\n        class=\"bg-inherit separator-top p-t-16 d-block\"\n        listTitle=\"{{ 'Multiple label and value pairs' | translate }}\"\n        name=\"datapoints\"\n        [defaultFormOptions]=\"defaultFormOptions\"\n        [config]=\"datapointSelectionConfig\"\n        [minActiveCount]=\"0\"\n        formControlName=\"datapointsLabels\"\n      ></c8y-datapoint-selection-list>\n\n      <c8y-datapoint-selection-list\n        class=\"bg-inherit separator-top p-t-16 d-block\"\n        listTitle=\"{{ 'Gauge`display`' | translate }}\"\n        name=\"datapoints\"\n        [defaultFormOptions]=\"defaultFormOptions\"\n        [config]=\"datapointSelectionConfig\"\n        [minActiveCount]=\"0\"\n        [maxActiveCount]=\"1\"\n        formControlName=\"datapointsGauge\"\n      ></c8y-datapoint-selection-list>\n    </div>\n  } @else {\n    <c8y-datapoint-selection-list\n      class=\"bg-inherit d-block\"\n      listTitle=\"{{ 'Data points`display`' | translate }}\"\n      name=\"datapoints\"\n      [defaultFormOptions]=\"defaultFormOptions\"\n      [config]=\"datapointSelectionConfig\"\n      [minActiveCount]=\"0\"\n      [maxActiveCount]=\"1\"\n      formControlName=\"datapointsGauge\"\n    ></c8y-datapoint-selection-list>\n\n    <c8y-form-group class=\"p-t-8 p-r-16 p-l-16\">\n      <label translate>Decimal places</label>\n      <input\n        class=\"form-control\"\n        name=\"fractionSize\"\n        type=\"number\"\n        formControlName=\"fractionSize\"\n        step=\"1\"\n      />\n      <c8y-messages [show]=\"formGroup.controls.fractionSize.errors\"></c8y-messages>\n    </c8y-form-group>\n\n    <div class=\"form-group p-r-16 p-l-16 m-b-0\">\n      <legend>\n        {{ 'Presets' | translate }}\n      </legend>\n      <c8y-preset-preview\n        formControlName=\"gaugePresetId\"\n        [ALL_GAUGE_PRESETS]=\"ALL_GAUGE_PRESETS\"\n        (onPresetChange)=\"onRadioPresetChange($event)\"\n      ></c8y-preset-preview>\n    </div>\n\n    <div class=\"p-16\">\n      <button\n        class=\"btn btn-default\"\n        aria-controls=\"advancedCollapse\"\n        [attr.aria-expanded]=\"showAdvancedOptions\"\n        type=\"button\"\n        (click)=\"showAdvancedOptions = !showAdvancedOptions\"\n      >\n        {{ showAdvancedOptions ? hideAdvancedOptionsLabel : showAdvancedOptionsLabel }}\n      </button>\n    </div>\n\n    <div\n      class=\"collapse\"\n      id=\"advancedCollapse\"\n      [collapse]=\"!showAdvancedOptions\"\n      [isAnimated]=\"true\"\n    >\n      <div\n        class=\"fit-h\"\n        style=\"min-height: 400px\"\n      >\n        <c8y-editor\n          [ngModel]=\"gaugeOptionsString\"\n          (ngModelChange)=\"gaugeJSONChange($event)\"\n          (editorInit)=\"assignSchema()\"\n          [ngModelOptions]=\"{ standalone: true }\"\n          monacoEditorMarkerValidator\n        ></c8y-editor>\n      </div>\n    </div>\n  }\n</form>\n\n<ng-template #gaugePreview>\n  @if (\n    (this.formGroup.value.datapointsGauge?.length > 0 && activeDatapointGauge) ||\n    (this.formGroup.value.datapointsLabels?.length > 0 && activeDatapointLabel)\n  ) {\n    <div style=\"height: 300px\">\n      <c8y-info-gauge-widget-view [config]=\"previewConfig\"></c8y-info-gauge-widget-view>\n    </div>\n  } @else {\n    <div class=\"d-col a-i-start j-c-center\">\n      <c8y-ui-empty-state\n        [icon]=\"'c8y-data-points'\"\n        [title]=\"'No data points selected' | translate\"\n        [subtitle]=\"'Select data point to render content' | translate\"\n        [horizontal]=\"false\"\n        data-cy=\"info-gauge--empty-state-no-data-point-selected\"\n      >\n        <p c8y-guide-docs>\n          <small translate>\n            Find out more in the\n            <a c8y-guide-href=\"/docs/cockpit/widgets-collection/#info-gauge\">user documentation</a>\n            .\n          </small>\n        </p>\n      </c8y-ui-empty-state>\n    </div>\n  }\n</ng-template>\n" }]
        }], ctorParameters: () => [{ type: i1$3.FormBuilder }, { type: i1$3.NgForm }, { type: i2.WidgetConfigComponent }, { type: i2.WidgetConfigService }, { type: i1.DynamicComponentComponent, decorators: [{
                    type: Optional
                }] }], propDecorators: { config: [{
                type: Input
            }], editorComponent: [{
                type: ViewChild,
                args: [EditorComponent]
            }], previewMapSet: [{
                type: ViewChild,
                args: ['gaugePreview']
            }] } });

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

export { GAUGE_PRESETS, GAUGE_PRESET_NAMES, InfoGaugeWidgetConfigComponent, InfoGaugeWidgetViewComponent };
//# sourceMappingURL=c8y-ngx-components-widgets-implementations-info-gauge.mjs.map