@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
239 lines • 76.1 kB
JavaScript
import { Component, inject, Input, Optional } from '@angular/core';
import { FormBuilder, NgForm, Validators } from '@angular/forms';
import { CommonModule, CoreModule, FormsModule, gettext, WidgetTimeContextDateRangeService } from '@c8y/ngx-components';
import { TranslateService } from '@ngx-translate/core';
import { takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { DatapointSelectorModule } from '@c8y/ngx-components/datapoint-selector';
import { omit } from 'lodash-es';
import { ContextDashboardComponent, WidgetConfigComponent } from '@c8y/ngx-components/context-dashboard';
import { AlarmEventSelectorModule } from '@c8y/ngx-components/alarm-event-selector';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { PopoverModule } from 'ngx-bootstrap/popover';
import { ChartAlarmsService, ChartEventsService, ChartsComponent, DATE_SELECTION_EXTENDED } from '@c8y/ngx-components/echart';
import { TimeContextComponent } from '@c8y/ngx-components/time-context';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components/context-dashboard";
import * as i2 from "@c8y/ngx-components";
import * as i3 from "@angular/common";
import * as i4 from "@angular/forms";
import * as i5 from "ngx-bootstrap/tooltip";
import * as i6 from "ngx-bootstrap/popover";
import * as i7 from "@c8y/ngx-components/datapoint-selector";
import * as i8 from "@c8y/ngx-components/alarm-event-selector";
export class DatapointsGraphWidgetConfigComponent {
constructor(widgetConfig, dashboardContextComponent) {
this.widgetConfig = widgetConfig;
this.dashboardContextComponent = dashboardContextComponent;
this.formBuilder = inject(FormBuilder);
this.form = inject(NgForm);
this.translate = inject(TranslateService);
this.widgetTimeContextDateRangeService = inject(WidgetTimeContextDateRangeService);
this.DATE_SELECTION = DATE_SELECTION_EXTENDED;
this.dateSelectionHelp = this.translate.instant(gettext(`Choose how to select a date range, the available options are:
<ul class="m-l-0 p-l-8 m-t-8 m-b-0">
<li>
<b>Widget configuration:</b>
restricts the date selection only to the widget configuration
</li>
<li>
<b>Widget and widget configuration:</b>
restricts the date selection to the widget view and widget configuration only
</li>
<li>
<b>Dashboard time range:</b>
restricts date selection to the global dashboard configuration only
</li>
</ul>`));
this.datapointSelectDefaultFormOptions = {
showRange: true,
showChart: true
};
this.datapointSelectionConfig = {};
this.activeDatapointsExists = false;
this.alarmsOrEventsHaveNoMatchingDps = false;
this.destroy$ = new Subject();
this.formGroup = this.initForm();
}
ngOnInit() {
this.config?.datapoints?.forEach(dp => this.assignContextFromContextDashboard(dp));
this.form.form.addControl('config', this.formGroup);
this.formGroup.patchValue(this.config || {});
this.formGroup.controls.alarms.setValue(this.config?.alarmsEventsConfigs?.filter(ae => ae.timelineType === 'ALARM'));
this.formGroup.controls.events.setValue(this.config?.alarmsEventsConfigs?.filter(ae => ae.timelineType === 'EVENT'));
this.initDateSelection();
this.setActiveDatapointsExists();
this.checkForMatchingDatapoints();
this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => {
this.config = {
...value,
alarmsEventsConfigs: [
...(this.formGroup.value.alarms || []),
...(this.formGroup.value.events || [])
]
};
this.setActiveDatapointsExists();
this.checkForMatchingDatapoints();
});
if (this.config?.widgetInstanceGlobalTimeContext) {
this.updateDashboardTimeContext(this.widgetTimeContextDateRangeService.initialTimeRange());
}
if (this.config.dateFrom && this.config.dateTo) {
this.timeProps = {
dateFrom: new Date(this.config?.dateFrom),
dateTo: new Date(this.config?.dateTo),
interval: this.config?.interval,
realtime: this.config?.realtime,
aggregation: this.config?.realtime ? null : this.config?.aggregation
};
}
}
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
onBeforeSave(config) {
if (this.formGroup.valid && config) {
Object.assign(config, omit(this.formGroup.value, ['alarms', 'events']), {
alarmsEventsConfigs: [
...(this.formGroup.value.alarms || []),
...(this.formGroup.value.events || [])
]
});
return true;
}
return false;
}
timePropsChanged(timeProps) {
if (timeProps.realtime !== this.config.realtime) {
this.formGroup.patchValue({ realtime: timeProps.realtime });
}
if (timeProps.realtime) {
if (timeProps.currentDateContextInterval !== this.formGroup.value.interval) {
this.formGroup.patchValue({ interval: timeProps.currentDateContextInterval });
}
return;
}
const patchValues = {
dateFrom: new Date(timeProps.currentDateContextFromDate),
dateTo: new Date(timeProps.currentDateContextToDate),
interval: timeProps.currentDateContextInterval,
...(timeProps.aggregation && { aggregation: timeProps.aggregation }),
...(timeProps.realtime && { realtime: timeProps.realtime })
};
this.formGroup.patchValue(patchValues);
}
updateDashboardTimeContext(timeProps) {
const initialTimeRange = {
dateFrom: timeProps.dateFrom,
dateTo: timeProps.dateTo,
interval: timeProps.interval || 'custom'
};
if (!this.widgetTimeContextDateRangeService.initialTimeRange()) {
this.widgetTimeContextDateRangeService.updateInitialTimeRange(initialTimeRange);
}
this.formGroup.patchValue({ ...timeProps, ...initialTimeRange });
}
updateTimeRangeOnRealtime(timeRange) {
this.formGroup.patchValue(timeRange, { emitEvent: false });
}
dateSelectionChange(dateSelection) {
this.dateSelection = dateSelection;
if (dateSelection === DATE_SELECTION_EXTENDED.CONFIG) {
this.formGroup.controls.displayDateSelection.enable();
this.formGroup.patchValue({ widgetInstanceGlobalTimeContext: false });
return;
}
// displayDateSelection should be false and disabled when dateSelection is not CONFIG
this.formGroup.controls.displayDateSelection.disable();
this.formGroup.patchValue({
widgetInstanceGlobalTimeContext: true,
realtime: false,
displayDateSelection: false
});
}
assignContextFromContextDashboard(datapoint) {
if (!this.dashboardContextComponent?.isDeviceTypeDashboard) {
return;
}
const context = this.widgetConfig?.context;
if (context?.id) {
const { name, id } = context;
datapoint.__target = { name, id };
this.datapointSelectionConfig.contextAsset = { id };
}
}
checkForMatchingDatapoints() {
const allMatch = this.config?.alarmsEventsConfigs?.every(ae => this.formGroup.value.datapoints?.some(dp => dp.__target?.id === ae.__target?.id));
queueMicrotask(() => {
if (allMatch) {
this.alarmsOrEventsHaveNoMatchingDps = false;
}
else {
this.alarmsOrEventsHaveNoMatchingDps = true;
}
});
}
initForm() {
const form = this.formBuilder.group({
datapoints: [
[],
[Validators.required, Validators.minLength(1)]
],
alarms: [[]],
events: [[]],
displayMarkedLine: [true, []],
displayMarkedPoint: [true, []],
mergeMatchingDatapoints: [true, []],
showLabelAndUnit: [true, []],
displayDateSelection: [false, []],
displayAggregationSelection: [false, []],
widgetInstanceGlobalTimeContext: [false, []],
canDecoupleGlobalTimeContext: [false, []],
dateFrom: [null, []],
dateTo: [null, []],
interval: ['days', [Validators.required]],
aggregation: [null, []],
realtime: [false, [Validators.required]],
showSlider: [true, [Validators.required]],
yAxisSplitLines: [false, [Validators.required]],
xAxisSplitLines: [false, [Validators.required]]
});
return form;
}
initDateSelection() {
if (!this.config?.widgetInstanceGlobalTimeContext) {
this.dateSelection = DATE_SELECTION_EXTENDED.CONFIG;
return;
}
this.dateSelection = DATE_SELECTION_EXTENDED.DASHBOARD_CONTEXT;
this.formGroup.controls.displayDateSelection.disable();
}
setActiveDatapointsExists() {
this.activeDatapointsExists =
(this.config?.datapoints?.filter(dp => dp.__active)?.length || 0) > 0;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DatapointsGraphWidgetConfigComponent, deps: [{ token: i1.WidgetConfigComponent, optional: true }, { token: i1.ContextDashboardComponent, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DatapointsGraphWidgetConfigComponent, isStandalone: true, selector: "c8y-datapoints-graph-widget-config", inputs: { config: "config" }, host: { classAttribute: "d-contents" }, providers: [ChartEventsService, ChartAlarmsService], ngImport: i0, template: "<div class=\"no-card-context d-flex-md fit-h--md\">\n <div class=\"col-md-5 bg-level-1 conf-col inner-scroll p-l-0\">\n <div class=\"p-l-24\">\n <form [formGroup]=\"formGroup\">\n <c8y-datapoint-selection-list\n class=\"bg-level-1 separator-bottom d-block\"\n name=\"datapoints\"\n [minActiveCount]=\"1\"\n [defaultFormOptions]=\"datapointSelectDefaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n formControlName=\"datapoints\"\n ></c8y-datapoint-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-level-1 separator-bottom d-block\"\n name=\"alarms\"\n formControlName=\"alarms\"\n [timelineType]=\"'ALARM'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"events\"\n formControlName=\"events\"\n [timelineType]=\"'EVENT'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n </form>\n </div>\n </div>\n\n <div class=\"col-md-7 sticky-top p-t-8 inner-scroll widget-preview\">\n <div class=\"p-r-24 d-col fit-h\">\n <div class=\"form-group p-t-8 form-group-sm d-flex a-i-center m-b-8\">\n <div class=\"d-flex a-i-center m-r-4\">\n <label\n class=\"m-b-0\"\n translate\n >\n Date selection\n </label>\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"dateSelectionHelpTemplate\"\n placement=\"bottom\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></button>\n </div>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control input-sm\"\n [ngModel]=\"dateSelection\"\n (ngModelChange)=\"dateSelectionChange($event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n <option\n title=\"{{ 'Dashboard time range' | translate }}\"\n [value]=\"DATE_SELECTION.DASHBOARD_CONTEXT\"\n >\n {{ 'Dashboard time range' | translate }}\n </option>\n <option\n title=\"{{ 'Widget configuration' | translate }}\"\n [value]=\"DATE_SELECTION.CONFIG\"\n >\n {{ 'Widget configuration' | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n <label class=\"text-12\">{{ 'Options' | translate }}</label>\n <c8y-time-context\n *ngIf=\"\n dateSelection === DATE_SELECTION.CONFIG &&\n formGroup.get('displayDateSelection').value === true\n \"\n [changedDateContext]=\"timeProps\"\n [controlsAvailable]=\"{\n realtime: true,\n timeRange: config?.displayDateSelection,\n interval: config?.displayDateSelection,\n aggregation: config?.displayAggregationSelection\n }\"\n (contextChange)=\"timePropsChanged($event)\"\n ></c8y-time-context>\n <c8y-charts\n class=\"d-block p-relative\"\n *ngIf=\"activeDatapointsExists\"\n [config]=\"config\"\n [alerts]=\"alerts\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n ></c8y-charts>\n\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 chart' | translate\"\n *ngIf=\"!activeDatapointsExists\"\n ></c8y-ui-empty-state>\n\n <form\n class=\"d-block p-t-8\"\n [formGroup]=\"formGroup\"\n >\n <label>{{ 'Display options' | translate }}</label>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Axis' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-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 axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching datapoints into single axis.</span>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Alarms & Events' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-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 <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 *ngIf=\"alarmsOrEventsHaveNoMatchingDps\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-warning\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Chart' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Enable date selection in the widget view.' | translate\"\n >\n <input\n name=\"displayDateSelection\"\n type=\"checkbox\"\n formControlName=\"displayDateSelection\"\n />\n <span></span>\n <span translate>Date selection in the widget view.</span>\n <button\n class=\"btn-clean m-l-8\"\n [attr.aria-label]=\"\n 'Date selection in widget view is not possible when using dashboard time range.'\n | translate\n \"\n [tooltip]=\"\n 'Date selection in widget view is not possible when using dashboard time range.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n *ngIf=\"dateSelection === DATE_SELECTION.DASHBOARD_CONTEXT\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Aggregation selection' | translate\"\n >\n <input\n name=\"displayAggregationSelection\"\n type=\"checkbox\"\n formControlName=\"displayAggregationSelection\"\n />\n <span></span>\n <span translate>Aggregation selection</span>\n </label>\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 </c8y-form-group>\n </fieldset>\n </form>\n </div>\n </div>\n</div>\n<ng-template #dateSelectionHelpTemplate>\n <div [innerHTML]=\"dateSelectionHelp\"></div>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: CoreModule }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.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: i6.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"], outputs: ["configChangeOnZoomOut", "timeRangeChangeOnRealtime", "datapointOutOfSync", "updateAlarmsAndEvents", "isMarkedAreaEnabled"] }, { kind: "ngmodule", type: DatapointSelectorModule }, { kind: "component", type: i7.DatapointSelectionListComponent, selector: "c8y-datapoint-selection-list", inputs: ["actions", "allowDragAndDrop", "config", "defaultFormOptions", "maxActiveCount", "minActiveCount", "resolveContext", "listTitle"], outputs: ["isValid", "change"] }, { kind: "ngmodule", type: AlarmEventSelectorModule }, { kind: "component", type: i8.AlarmEventSelectionListComponent, selector: "c8y-alarm-event-selection-list", inputs: ["timelineType", "canRemove", "canEdit", "canDragAndDrop", "title", "addButtonLabel", "hideSource", "inline", "activeToggleAsSwitch", "omitProperties", "datapoints", "config"] }, { kind: "component", type: TimeContextComponent, selector: "c8y-time-context", inputs: ["changedDateContext", "controlsAvailable", "context"], outputs: ["contextChange"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", 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,
TimeContextComponent
], providers: [ChartEventsService, ChartAlarmsService], template: "<div class=\"no-card-context d-flex-md fit-h--md\">\n <div class=\"col-md-5 bg-level-1 conf-col inner-scroll p-l-0\">\n <div class=\"p-l-24\">\n <form [formGroup]=\"formGroup\">\n <c8y-datapoint-selection-list\n class=\"bg-level-1 separator-bottom d-block\"\n name=\"datapoints\"\n [minActiveCount]=\"1\"\n [defaultFormOptions]=\"datapointSelectDefaultFormOptions\"\n [config]=\"datapointSelectionConfig\"\n formControlName=\"datapoints\"\n ></c8y-datapoint-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-level-1 separator-bottom d-block\"\n name=\"alarms\"\n formControlName=\"alarms\"\n [timelineType]=\"'ALARM'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n\n <c8y-alarm-event-selection-list\n class=\"bg-inherit\"\n name=\"events\"\n formControlName=\"events\"\n [timelineType]=\"'EVENT'\"\n [datapoints]=\"config?.datapoints\"\n ></c8y-alarm-event-selection-list>\n </form>\n </div>\n </div>\n\n <div class=\"col-md-7 sticky-top p-t-8 inner-scroll widget-preview\">\n <div class=\"p-r-24 d-col fit-h\">\n <div class=\"form-group p-t-8 form-group-sm d-flex a-i-center m-b-8\">\n <div class=\"d-flex a-i-center m-r-4\">\n <label\n class=\"m-b-0\"\n translate\n >\n Date selection\n </label>\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"dateSelectionHelpTemplate\"\n placement=\"bottom\"\n triggers=\"focus\"\n container=\"body\"\n [adaptivePosition]=\"false\"\n ></button>\n </div>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control input-sm\"\n [ngModel]=\"dateSelection\"\n (ngModelChange)=\"dateSelectionChange($event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n >\n <option\n title=\"{{ 'Dashboard time range' | translate }}\"\n [value]=\"DATE_SELECTION.DASHBOARD_CONTEXT\"\n >\n {{ 'Dashboard time range' | translate }}\n </option>\n <option\n title=\"{{ 'Widget configuration' | translate }}\"\n [value]=\"DATE_SELECTION.CONFIG\"\n >\n {{ 'Widget configuration' | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n <label class=\"text-12\">{{ 'Options' | translate }}</label>\n <c8y-time-context\n *ngIf=\"\n dateSelection === DATE_SELECTION.CONFIG &&\n formGroup.get('displayDateSelection').value === true\n \"\n [changedDateContext]=\"timeProps\"\n [controlsAvailable]=\"{\n realtime: true,\n timeRange: config?.displayDateSelection,\n interval: config?.displayDateSelection,\n aggregation: config?.displayAggregationSelection\n }\"\n (contextChange)=\"timePropsChanged($event)\"\n ></c8y-time-context>\n <c8y-charts\n class=\"d-block p-relative\"\n *ngIf=\"activeDatapointsExists\"\n [config]=\"config\"\n [alerts]=\"alerts\"\n (timeRangeChangeOnRealtime)=\"updateTimeRangeOnRealtime($event)\"\n (configChangeOnZoomOut)=\"updateDashboardTimeContext($event)\"\n ></c8y-charts>\n\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 chart' | translate\"\n *ngIf=\"!activeDatapointsExists\"\n ></c8y-ui-empty-state>\n\n <form\n class=\"d-block p-t-8\"\n [formGroup]=\"formGroup\"\n >\n <label>{{ 'Display options' | translate }}</label>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Axis' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-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 axis' | translate\"\n >\n <input\n name=\"mergeMatchingDatapoints\"\n type=\"checkbox\"\n formControlName=\"mergeMatchingDatapoints\"\n />\n <span></span>\n <span translate>Merge matching datapoints into single axis.</span>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Alarms & Events' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-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 <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 *ngIf=\"alarmsOrEventsHaveNoMatchingDps\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-warning\"\n c8yIcon=\"exclamation-triangle\"\n ></i>\n </button>\n </label>\n </c8y-form-group>\n </fieldset>\n <fieldset class=\"c8y-fieldset m-b-24 m-t-0\">\n <legend>{{ 'Chart' | translate }}</legend>\n <c8y-form-group class=\"p-b-16 m-b-0 p-t-8 form-group-sm\">\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Enable date selection in the widget view.' | translate\"\n >\n <input\n name=\"displayDateSelection\"\n type=\"checkbox\"\n formControlName=\"displayDateSelection\"\n />\n <span></span>\n <span translate>Date selection in the widget view.</span>\n <button\n class=\"btn-clean m-l-8\"\n [attr.aria-label]=\"\n 'Date selection in widget view is not possible when using dashboard time range.'\n | translate\n \"\n [tooltip]=\"\n 'Date selection in widget view is not possible when using dashboard time range.'\n | translate\n \"\n container=\"body\"\n type=\"button\"\n *ngIf=\"dateSelection === DATE_SELECTION.DASHBOARD_CONTEXT\"\n (click)=\"$event.stopPropagation()\"\n [adaptivePosition]=\"false\"\n >\n <i\n class=\"text-info\"\n c8yIcon=\"info\"\n ></i>\n </button>\n </label>\n <label\n class=\"c8y-checkbox\"\n [title]=\"'Aggregation selection' | translate\"\n >\n <input\n name=\"displayAggregationSelection\"\n type=\"checkbox\"\n formControlName=\"displayAggregationSelection\"\n />\n <span></span>\n <span translate>Aggregation selection</span>\n </label>\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 </c8y-form-group>\n </fieldset>\n </form>\n </div>\n </div>\n</div>\n<ng-template #dateSelectionHelpTemplate>\n <div [innerHTML]=\"dateSelectionHelp\"></div>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1.WidgetConfigComponent, decorators: [{
type: Optional
}] }, { type: i1.ContextDashboardComponent, decorators: [{
type: Optional
}] }], propDecorators: { config: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YXBvaW50cy1ncmFwaC13aWRnZXQtY29uZmlnLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3dpZGdldHMvaW1wbGVtZW50YXRpb25zL2RhdGFwb2ludHMtZ3JhcGgvZGF0YXBvaW50cy1ncmFwaC1jb25maWcvZGF0YXBvaW50cy1ncmFwaC13aWRnZXQtY29uZmlnLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3dpZGdldHMvaW1wbGVtZW50YXRpb25zL2RhdGFwb2ludHMtZ3JhcGgvZGF0YXBvaW50cy1ncmFwaC1jb25maWcvZGF0YXBvaW50cy1ncmFwaC13aWRnZXQtY29uZmlnLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBcUIsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpFLE9BQU8sRUFDTCxZQUFZLEVBQ1osVUFBVSxFQUVWLFdBQVcsRUFDWCxPQUFPLEVBRVAsaUNBQWlDLEVBQ2xDLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUdMLHVCQUF1QixFQUV4QixNQUFNLHdDQUF3QyxDQUFDO0FBQ2hELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFakMsT0FBTyxFQUNMLHlCQUF5QixFQUN6QixxQkFBcUIsRUFDdEIsTUFBTSx1Q0FBdUMsQ0FBQztBQUMvQyxPQUFPLEVBRUwsd0JBQXdCLEVBRXpC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VUE0UkEsMkNEdk9JLFlBQVksdWdCQUNaLFVBQVUsb3ZEQUNWLFdBQVcsOEJBQ1gsYUFBYSxpa0JBQ2IsYUFBYSwrVkFDYixlQUFlLDJOQUNmLHVCQUF1QixxVEFDdkIsd0JBQXdCLHNVQUN4QixvQkFBb0I7OzRGQUlYLG9DQUFvQztrQkFsQmhELFNBQVM7K0JBQ0Usb0NBQW9DLFFBQ3hDLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxjQUVqQixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixVQUFVO3dCQUNWLFdBQVc7d0JBQ1gsYUFBYTt3QkFDYixhQUFhO3dCQUNiLGVBQWU7d0JBQ2YsdUJBQXVCO3dCQUN2Qix3QkFBd0I7d0JBQ3hCLG9CQUFvQjtxQkFDckIsYUFDVSxDQUFDLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDOzswQkEwQ2hELFFBQVE7OzBCQUNSLFFBQVE7eUNBeENGLE1BQU07c0JBQWQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgaW5qZWN0LCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBGb3JtQnVpbGRlciwgTmdGb3JtLCBWYWxpZGF0b3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMvaW50ZXJuYWwvT2JzZXJ2YWJsZSc7XG5pbXBvcnQge1xuICBDb21tb25Nb2R1bGUsXG4gIENvcmVNb2R1bGUsXG4gIER5bmFtaWNDb21wb25lbnRBbGVydEFnZ3JlZ2F0b3IsXG4gIEZvcm1zTW9kdWxlLFxuICBnZXR0ZXh0LFxuICBPbkJlZm9yZVNhdmUsXG4gIFdpZGdldFRpbWVDb250ZXh0RGF0ZVJhbmdlU2VydmljZVxufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7XG4gIERhdGFwb2ludEF0dHJpYnV0ZXNGb3JtQ29uZmlnLFxuICBEYXRhcG9pbnRTZWxlY3Rvck1vZGFsT3B0aW9ucyxcbiAgRGF0YXBvaW50U2VsZWN0b3JNb2R1bGUsXG4gIEtQSURldGFpbHNcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9kYXRhcG9pbnQtc2VsZWN0b3InO1xuaW1wb3J0IHsgb21pdCB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyBhZ2dyZWdhdGlvblR5cGUgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQge1xuICBDb250ZXh0RGFzaGJvYXJkQ29tcG9uZW50LFxuICBXaWRnZXRDb25maWdDb21wb25lbnRcbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9jb250ZXh0LWRhc2hib2FyZCc7XG5pbXBvcnQge1xuICBBbGFybURldGFpbHMsXG4gIEFsYXJtRXZlbnRTZWxlY3Rvck1vZHVsZSxcbiAgRXZlbnREZXRhaWxzXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMvYWxhcm0tZXZlbnQtc2VsZWN0b3InO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ25neC1ib290c3RyYXAvdG9vbHRpcCc7XG5pbXBvcnQgeyBQb3BvdmVyTW9kdWxlIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC9wb3BvdmVyJztcbmltcG9ydCB7XG4gIENoYXJ0QWxhcm1zU2VydmljZSxcbiAgQ2hhcnRFdmVudHNTZXJ2aWNlLFxuICBDaGFydHNDb21wb25lbnQsXG4gIERhdGFwb2ludHNHcmFwaEtQSURldGFpbHMsXG4gIERhdGFwb2ludHNHcmFwaFdpZGdldENvbmZpZyxcbiAgRGF0YXBvaW50c0dyYXBoV2lkZ2V0VGltZVByb3BzLFxuICBEQVRFX1NFTEVDVElPTl9FWFRFTkRFRCxcbiAgVGltZUNvbnRleHRQcm9wc1xufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzL2VjaGFydC