@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
301 lines (296 loc) • 32.5 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, inject, DestroyRef, model, ViewChild, Input, Component } from '@angular/core';
import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
import * as i3 from '@angular/forms';
import { FormBuilder } from '@angular/forms';
import * as i1 from '@c8y/ngx-components';
import { AGGREGATION_LIMITS, CoreModule, DateTimePickerModule, AggregationPickerComponent, RealtimeControlComponent } from '@c8y/ngx-components';
import { INTERVALS, TimeSpanInMs, INTERVAL_TITLES, IntervalPickerComponent } from '@c8y/ngx-components/interval-picker';
import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
import * as i4 from 'ngx-bootstrap/dropdown';
import { BsDropdownModule, BsDropdownDirective } from 'ngx-bootstrap/dropdown';
import * as i5 from 'ngx-bootstrap/tooltip';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { interval } from 'rxjs';
import { aggregationType } from '@c8y/client';
import * as i2 from '@angular/common';
class DatapointExplorerService {
constructor() {
this.DEFAULT_INTERVAL = 'days';
}
// Create generic? Based on packages/ngx-components/core/dashboard/wiget-time-context/widget-time-context.component.html
getDefaultContext() {
return {
date: this.getDateTimeContextByInterval(this.DEFAULT_INTERVAL),
interval: this.DEFAULT_INTERVAL,
realtime: false,
aggregation: aggregationType.MINUTELY
};
}
calculateAggregation([dateFrom, dateTo], requestedAggregation) {
const timeRangeValidations = this.validateTimeRanges([dateFrom, dateTo]);
const disabledAggregations = this.getDisabledAggregations(timeRangeValidations);
const timeRangeInMs = this.getTimeRangeInMs(dateFrom, dateTo);
const isRequestedAggregationValid = requestedAggregation === null || !disabledAggregations[requestedAggregation];
const selectedAggregation = isRequestedAggregationValid
? requestedAggregation
: this.determineAggregation(timeRangeInMs);
return {
selectedAggregation,
disabledAggregations
};
}
getDateTimeContextByInterval(intervalId) {
const interval = INTERVALS.find(({ id }) => id === intervalId);
const dateTo = new Date();
const dateFrom = new Date(dateTo.valueOf() - interval.timespanInMs);
return [dateFrom, dateTo];
}
getTimeRangeInMs(dateFrom, dateTo) {
return dateTo.valueOf() - dateFrom.valueOf();
}
validateTimeRanges([dateFrom, dateTo]) {
const timeRangeInMs = this.getTimeRangeInMs(dateFrom, dateTo);
return [
{
aggregationType: aggregationType.DAILY,
isDisabled: timeRangeInMs <= TimeSpanInMs.DAY
},
{
aggregationType: aggregationType.HOURLY,
isDisabled: timeRangeInMs <= TimeSpanInMs.HOUR
},
{
aggregationType: aggregationType.MINUTELY,
isDisabled: timeRangeInMs <= TimeSpanInMs.MINUTE
}
];
}
getDisabledAggregations(timeRangeValidations) {
return timeRangeValidations.reduce((acc, { aggregationType, isDisabled }) => ({
...acc,
[aggregationType]: isDisabled
}), {});
}
determineAggregation(timeRangeInMs) {
if (timeRangeInMs >= AGGREGATION_LIMITS.DAILY_LIMIT) {
return aggregationType.DAILY;
}
else if (timeRangeInMs >= AGGREGATION_LIMITS.HOURLY_LIMIT) {
return aggregationType.HOURLY;
}
else if (timeRangeInMs >= AGGREGATION_LIMITS.MINUTELY_LIMIT) {
return aggregationType.MINUTELY;
}
return null;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointExplorerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointExplorerService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: DatapointExplorerService, decorators: [{
type: Injectable,
args: [{ providedIn: 'root' }]
}] });
class TimeContextComponent {
#destroyRef;
constructor(widgetTimeContextDateRangeService) {
this.widgetTimeContextDateRangeService = widgetTimeContextDateRangeService;
this.datapointExplorerService = inject(DatapointExplorerService);
this.formBuilder = inject(FormBuilder);
this.#destroyRef = inject(DestroyRef);
this.DATE_FORMAT = 'short';
this.INTERVAL_TITLES = INTERVAL_TITLES;
this.REALTIME_INTERVAL = 1000;
this.form = this.createForm(this.datapointExplorerService.getDefaultContext());
this.valuesSignal = toSignal(this.form.controls.currentDateContextFromDate.valueChanges, {
initialValue: this.form.controls.currentDateContextFromDate.value
});
this.context = model(this.form.value);
const context = this.datapointExplorerService.getDefaultContext();
const { disabledAggregations } = this.datapointExplorerService.calculateAggregation(context.date, context.aggregation);
this.disabledAggregations = disabledAggregations;
this.subscribeToIntervalChange();
this.subscribeToRealtimeChange();
this.subscribeToAggregationChange();
}
ngOnChanges(changes) {
if (changes.changedDateContext && changes.changedDateContext.currentValue) {
this.update({
date: [this.changedDateContext.dateFrom, this.changedDateContext.dateTo],
interval: this.changedDateContext.interval,
realtime: this.changedDateContext.realtime || false,
aggregation: this.changedDateContext.aggregation
});
if (this.changedDateContext.realtime) {
this.form.controls.aggregation.disable();
}
}
}
applyDatetimeContext() {
this.update({
date: [
new Date(this.form.controls.temporaryUserSelectedFromDate.value),
new Date(this.form.controls.temporaryUserSelectedToDate.value)
],
interval: 'custom',
realtime: this.form.value.realtime,
aggregation: this.form.value.aggregation
});
}
subscribeToIntervalChange() {
this.form.controls.currentDateContextInterval.valueChanges
.pipe(takeUntilDestroyed(this.#destroyRef))
.subscribe(interval => {
let date;
this.widgetTimeContextDateRangeService.updateInitialTimeRange(null);
if (interval === 'custom') {
date = [
new Date(this.form.controls.currentDateContextFromDate.value),
new Date(this.form.controls.currentDateContextToDate.value)
];
}
else {
date = this.datapointExplorerService.getDateTimeContextByInterval(interval);
this.dropdown.isOpen = false;
}
this.update({
date,
interval,
realtime: this.form.value.realtime,
aggregation: this.form.value.aggregation
});
});
}
subscribeToRealtimeChange() {
this.form.controls.realtime.valueChanges
.pipe(takeUntilDestroyed(this.#destroyRef))
.subscribe(realtime => {
this.onRealtimeValueChange(realtime);
if (realtime) {
this.startRealtime();
}
else {
this.stopRealtime();
}
});
}
subscribeToAggregationChange() {
this.form.controls.aggregation.valueChanges
.pipe(takeUntilDestroyed(this.#destroyRef))
.subscribe(aggregation => {
this.update({
date: [
new Date(this.form.value.currentDateContextFromDate),
new Date(this.form.value.currentDateContextToDate)
],
interval: this.form.value.currentDateContextInterval,
realtime: this.form.value.realtime,
aggregation
});
});
}
onRealtimeValueChange(realtime) {
let dateTimeContext;
if (this.form.value.currentDateContextInterval !== 'custom') {
dateTimeContext = this.datapointExplorerService.getDateTimeContextByInterval(this.form.value.currentDateContextInterval);
}
else {
const currentTimeSpanInMs = new Date(this.form.value.currentDateContextToDate).valueOf() -
new Date(this.form.value.currentDateContextFromDate).valueOf();
const dateTo = new Date();
const dateFrom = new Date(dateTo.valueOf() - currentTimeSpanInMs);
dateTimeContext = [dateFrom, dateTo];
}
this.update({
date: dateTimeContext,
interval: this.form.value.currentDateContextInterval,
realtime,
aggregation: null
});
}
startRealtime() {
this.form.controls.temporaryUserSelectedFromDate.disable();
this.form.controls.temporaryUserSelectedToDate.disable();
this.form.controls.aggregation.disable();
this.realtimeSubscription = interval(this.REALTIME_INTERVAL)
.pipe(takeUntilDestroyed(this.#destroyRef))
.subscribe(() => {
if (!this.form.value.realtime) {
this.realtimeSubscription.unsubscribe();
return;
}
const newDateFrom = new Date(new Date(this.form.value.currentDateContextFromDate).valueOf() + this.REALTIME_INTERVAL);
const newDateTo = new Date(new Date(this.form.value.currentDateContextToDate).valueOf() + this.REALTIME_INTERVAL);
this.updateFormValues({
date: [newDateFrom, newDateTo],
interval: this.form.value.currentDateContextInterval,
realtime: true,
aggregation: null
});
});
}
stopRealtime() {
this.realtimeSubscription?.unsubscribe();
this.form?.controls.temporaryUserSelectedFromDate.enable();
this.form?.controls.temporaryUserSelectedToDate.enable();
this.form?.controls.aggregation.enable();
}
update({ date, interval, realtime, aggregation }) {
const { selectedAggregation, disabledAggregations } = this.datapointExplorerService.calculateAggregation(date, aggregation);
this.disabledAggregations = disabledAggregations;
this.updateFormValues({ date, interval, realtime, aggregation: selectedAggregation });
}
createForm(context) {
return this.formBuilder.group({
temporaryUserSelectedFromDate: context.date[0].toISOString(),
temporaryUserSelectedToDate: context.date[1].toISOString(),
currentDateContextFromDate: context.date[0].toISOString(),
currentDateContextToDate: context.date[1].toISOString(),
currentDateContextInterval: context.interval || 'custom',
realtime: context.realtime,
aggregation: context.aggregation
});
}
updateFormValues({ date, interval, realtime, aggregation }) {
const newFormValues = {
temporaryUserSelectedFromDate: date[0].toISOString(),
temporaryUserSelectedToDate: date[1].toISOString(),
currentDateContextFromDate: date[0].toISOString(),
currentDateContextToDate: date[1].toISOString(),
realtime,
currentDateContextInterval: interval || 'custom',
aggregation: aggregation || null
};
this.context.set(newFormValues);
this.form.patchValue(newFormValues, {
emitEvent: false
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TimeContextComponent, deps: [{ token: i1.WidgetTimeContextDateRangeService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.14", type: TimeContextComponent, isStandalone: true, selector: "c8y-time-context", inputs: { changedDateContext: { classPropertyName: "changedDateContext", publicName: "changedDateContext", isSignal: false, isRequired: false, transformFunction: null }, controlsAvailable: { classPropertyName: "controlsAvailable", publicName: "controlsAvailable", isSignal: false, isRequired: false, transformFunction: null }, context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { context: "contextChange" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: BsDropdownDirective, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<ng-container *ngIf=\"controlsAvailable; else actionBarTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n</ng-container>\n\n<ng-template #actionBarTemplate>\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n</ng-template>\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n *ngIf=\"date\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n <c8y-aggregation-picker\n *ngIf=\"controlsAvailable ? controlsAvailable.aggregation : true\"\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n </div>\n </form>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CoreModule }, { kind: "component", type: i1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i1.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }, { kind: "directive", type: i3.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "component", type: i1.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i1.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i1.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i1.DateTimePickerComponent, selector: "c8y-date-time-picker", inputs: ["minDate", "maxDate", "placeholder", "dateInputFormat", "adaptivePosition", "size", "dateType", "config"], outputs: ["onDateSelected"] }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "ngmodule", type: DateTimePickerModule }, { kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i4.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i4.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i4.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "component", type: AggregationPickerComponent, selector: "c8y-aggregation-picker", inputs: ["disabledAggregations"] }, { 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: "component", type: IntervalPickerComponent, selector: "c8y-interval-picker", inputs: ["INTERVALS"] }, { kind: "component", type: RealtimeControlComponent, selector: "c8y-realtime-control" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TimeContextComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-time-context', standalone: true, imports: [
CoreModule,
BsDatepickerModule,
DateTimePickerModule,
BsDropdownModule,
AggregationPickerComponent,
TooltipModule,
IntervalPickerComponent,
RealtimeControlComponent
], template: "<ng-container *ngIf=\"controlsAvailable; else actionBarTemplate\">\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n</ng-container>\n\n<ng-template #actionBarTemplate>\n <c8y-action-bar-item\n [groupId]=\"'timeContext'\"\n [inGroupPriority]=\"1\"\n [placement]=\"'left'\"\n >\n <ng-container\n [ngTemplateOutlet]=\"dateTimePicker\"\n [ngTemplateOutletContext]=\"{\n date: [form.value.currentDateContextFromDate, form.value.currentDateContextToDate]\n }\"\n ></ng-container>\n </c8y-action-bar-item>\n</ng-template>\n\n<ng-template\n #dateTimePicker\n let-date=\"date\"\n>\n <form\n class=\"d-flex gap-8 p-l-xs-16 p-r-xs-16 m-t-xs-8 m-b-xs-8\"\n [formGroup]=\"form\"\n >\n <ng-container>\n <div\n class=\"dropdown flex-grow\"\n #dropdown=\"bs-dropdown\"\n dropdown\n [insideClick]=\"true\"\n *ngIf=\"date\"\n >\n <button\n class=\"dropdown-toggle form-control l-h-tight d-flex a-i-center\"\n attr.aria-label=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{\n date[1] | c8yDate: DATE_FORMAT\n }}\"\n tooltip=\"{{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\"\n placement=\"top\"\n container=\"body\"\n data-cy=\"widget-time-context--date-picker-dropdown-button\"\n [adaptivePosition]=\"false\"\n [delay]=\"500\"\n dropdownToggle\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"schedule1\"\n ></i>\n <div class=\"d-col text-left fit-w\">\n <span\n class=\"text-12\"\n data-cy=\"widget-time-context--selected-interval\"\n >\n {{ INTERVAL_TITLES[form.controls.currentDateContextInterval.value] | translate }}\n </span>\n <span\n class=\"text-10 text-muted text-truncate\"\n data-cy=\"widget-time-context--selected-time-range\"\n >\n {{ date[0] | c8yDate: DATE_FORMAT }} \u2014 {{ date[1] | c8yDate: DATE_FORMAT }}\n </span>\n </div>\n <span class=\"caret m-r-16 m-l-4\"></span>\n </button>\n\n <ul\n class=\"dropdown-menu dropdown-menu--date-range\"\n *dropdownMenu\n >\n <c8y-interval-picker\n class=\"d-contents\"\n formControlName=\"currentDateContextInterval\"\n ></c8y-interval-picker>\n\n <ng-container *ngIf=\"form.controls.currentDateContextInterval.value === 'custom'\">\n <div class=\"p-l-16 p-r-16\">\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'From`date`' | translate\"\n for=\"temporaryUserSelectedFromDate\"\n translate\n >\n From`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedFromDate\"\n [maxDate]=\"form.value.temporaryUserSelectedToDate\"\n [placeholder]=\"'From`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedFromDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedFromDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedFromDate.errors\">\n <c8y-message\n name=\"dateAfterRangeMax\"\n [text]=\"'This date is after the latest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n\n <c8y-form-group\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n >\n <label\n [title]=\"'To`date`' | translate\"\n for=\"temporaryUserSelectedToDate\"\n translate\n >\n To`date`\n </label>\n <c8y-date-time-picker\n id=\"temporaryUserSelectedToDate\"\n [minDate]=\"form.value.temporaryUserSelectedFromDate\"\n [placeholder]=\"'To`date`' | translate\"\n [formControl]=\"form.controls.temporaryUserSelectedToDate\"\n [ngClass]=\"form.controls.temporaryUserSelectedToDate.errors ? 'has-error' : ''\"\n ></c8y-date-time-picker>\n <c8y-messages [show]=\"form.controls.temporaryUserSelectedToDate.errors\">\n <c8y-message\n name=\"dateBeforeRangeMin\"\n [text]=\"'This date is before the earliest allowed date.' | translate\"\n ></c8y-message>\n <c8y-message\n name=\"invalidDateTime\"\n [text]=\"'This date is invalid.' | translate\"\n ></c8y-message>\n </c8y-messages>\n </c8y-form-group>\n </div>\n\n <div class=\"p-16 d-flex gap-8 separator-top\">\n <button\n class=\"btn btn-default btn-sm flex-grow\"\n title=\"{{ 'Reset' | translate }}\"\n type=\"button\"\n (click)=\"dropdown.isOpen = false\"\n [disabled]=\"form.value.realtime\"\n translate\n >\n Reset\n </button>\n\n <button\n class=\"btn btn-primary btn-sm flex-grow\"\n title=\"{{ 'Apply' | translate }}\"\n type=\"button\"\n (click)=\"applyDatetimeContext(); dropdown.isOpen = false\"\n [disabled]=\"\n (form.pristine && form.untouched) || form.invalid || form.value.realtime\n \"\n translate\n >\n Apply\n </button>\n </div>\n </ng-container>\n </ul>\n </div>\n </ng-container>\n\n <div class=\"input-group w-auto\">\n <c8y-realtime-control\n class=\"form-control p-0 flex-no-grow w-auto\"\n formControlName=\"realtime\"\n ></c8y-realtime-control>\n\n <c8y-aggregation-picker\n *ngIf=\"controlsAvailable ? controlsAvailable.aggregation : true\"\n formControlName=\"aggregation\"\n [disabledAggregations]=\"disabledAggregations\"\n ></c8y-aggregation-picker>\n </div>\n </form>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1.WidgetTimeContextDateRangeService }], propDecorators: { changedDateContext: [{
type: Input
}], controlsAvailable: [{
type: Input
}], dropdown: [{
type: ViewChild,
args: [BsDropdownDirective]
}] } });
/**
* Generated bundle index. Do not edit.
*/
export { TimeContextComponent };
//# sourceMappingURL=c8y-ngx-components-time-context.mjs.map