UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

301 lines (296 loc) 32.5 kB
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