thingsboard/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts

384 lines
14 KiB
TypeScript
Raw Normal View History

2019-08-12 19:34:23 +03:00
///
2023-01-31 10:43:56 +02:00
/// Copyright © 2016-2023 The Thingsboard Authors
2019-08-12 19:34:23 +03:00
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
2023-02-09 12:19:40 +02:00
import { Component, Inject, InjectionToken, OnInit, ViewContainerRef } from '@angular/core';
2019-08-12 19:34:23 +03:00
import {
aggregationTranslations,
AggregationType,
DAY,
HistoryWindowType,
QuickTimeInterval,
quickTimeIntervalPeriod,
RealtimeWindowType,
2019-08-12 19:34:23 +03:00
Timewindow,
TimewindowType
} from '@shared/models/time/time.models';
import { PageComponent } from '@shared/components/page.component';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
2023-02-02 15:55:06 +02:00
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
2019-08-12 19:34:23 +03:00
import { TimeService } from '@core/services/time.service';
2023-02-07 17:45:03 +02:00
import { isDefined } from '@core/utils';
2023-02-09 12:19:40 +02:00
import { OverlayRef } from '@angular/cdk/overlay';
2019-08-12 19:34:23 +03:00
export interface TimewindowPanelData {
historyOnly: boolean;
forAllTimeEnabled: boolean;
quickIntervalOnly: boolean;
2019-08-12 19:34:23 +03:00
timewindow: Timewindow;
aggregation: boolean;
2021-03-17 18:38:57 +02:00
timezone: boolean;
2020-02-25 19:11:25 +02:00
isEdit: boolean;
2019-08-12 19:34:23 +03:00
}
2023-02-09 12:19:40 +02:00
export const TIMEWINDOW_PANEL_DATA = new InjectionToken<any>('TimewindowPanelData');
2019-08-12 19:34:23 +03:00
@Component({
selector: 'tb-timewindow-panel',
templateUrl: './timewindow-panel.component.html',
styleUrls: ['./timewindow-panel.component.scss']
})
export class TimewindowPanelComponent extends PageComponent implements OnInit {
historyOnly = false;
forAllTimeEnabled = false;
quickIntervalOnly = false;
2019-08-12 19:34:23 +03:00
aggregation = false;
2021-03-17 18:38:57 +02:00
timezone = false;
2020-02-25 19:11:25 +02:00
isEdit = false;
2019-08-12 19:34:23 +03:00
timewindow: Timewindow;
2023-02-02 15:55:06 +02:00
timewindowForm: UntypedFormGroup;
2019-08-12 19:34:23 +03:00
historyTypes = HistoryWindowType;
realtimeTypes = RealtimeWindowType;
2019-08-12 19:34:23 +03:00
timewindowTypes = TimewindowType;
aggregationTypes = AggregationType;
aggregations = Object.keys(AggregationType);
aggregationTypesTranslations = aggregationTranslations;
2023-02-09 12:19:40 +02:00
result: Timewindow;
2023-02-07 17:45:03 +02:00
2023-02-09 12:19:40 +02:00
constructor(@Inject(TIMEWINDOW_PANEL_DATA) public data: TimewindowPanelData,
public overlayRef: OverlayRef,
protected store: Store<AppState>,
2023-02-02 15:55:06 +02:00
public fb: UntypedFormBuilder,
2019-08-12 19:34:23 +03:00
private timeService: TimeService,
public viewContainerRef: ViewContainerRef) {
super(store);
2023-02-09 12:19:40 +02:00
this.historyOnly = data.historyOnly;
this.forAllTimeEnabled = data.forAllTimeEnabled;
2023-02-09 12:19:40 +02:00
this.quickIntervalOnly = data.quickIntervalOnly;
this.timewindow = data.timewindow;
this.aggregation = data.aggregation;
this.timezone = data.timezone;
this.isEdit = data.isEdit;
2019-08-12 19:34:23 +03:00
}
ngOnInit(): void {
2020-02-25 19:11:25 +02:00
const hideInterval = this.timewindow.hideInterval || false;
const hideLastInterval = this.timewindow.hideLastInterval || false;
const hideQuickInterval = this.timewindow.hideQuickInterval || false;
2020-02-25 19:11:25 +02:00
const hideAggregation = this.timewindow.hideAggregation || false;
const hideAggInterval = this.timewindow.hideAggInterval || false;
2021-03-17 18:38:57 +02:00
const hideTimezone = this.timewindow.hideTimezone || false;
2020-02-25 19:11:25 +02:00
2023-02-07 17:45:03 +02:00
const realtime = this.timewindow.realtime;
const history = this.timewindow.history;
const aggregation = this.timewindow.aggregation;
2019-08-12 19:34:23 +03:00
this.timewindowForm = this.fb.group({
2023-02-07 17:45:03 +02:00
realtime: this.fb.group({
realtimeType: [{
2023-02-09 12:19:40 +02:00
value: isDefined(realtime?.realtimeType) ? this.timewindow.realtime.realtimeType : RealtimeWindowType.LAST_INTERVAL,
2023-02-07 17:45:03 +02:00
disabled: hideInterval
}],
timewindowMs: [{
2023-02-09 12:19:40 +02:00
value: isDefined(realtime?.timewindowMs) ? this.timewindow.realtime.timewindowMs : null,
2023-02-07 17:45:03 +02:00
disabled: hideInterval || hideLastInterval
}],
2023-02-09 12:19:40 +02:00
interval: [isDefined(realtime?.interval) ? this.timewindow.realtime.interval : null],
2023-02-07 17:45:03 +02:00
quickInterval: [{
2023-02-09 12:19:40 +02:00
value: isDefined(realtime?.quickInterval) ? this.timewindow.realtime.quickInterval : null,
2023-02-07 17:45:03 +02:00
disabled: hideInterval || hideQuickInterval
}]
}),
history: this.fb.group({
historyType: [{
2023-02-09 12:19:40 +02:00
value: isDefined(history?.historyType) ? this.timewindow.history.historyType : HistoryWindowType.LAST_INTERVAL,
2023-02-07 17:45:03 +02:00
disabled: hideInterval
}],
timewindowMs: [{
2023-02-09 12:19:40 +02:00
value: isDefined(history?.timewindowMs) ? this.timewindow.history.timewindowMs : null,
2023-02-07 17:45:03 +02:00
disabled: hideInterval
}],
2023-02-09 12:19:40 +02:00
interval: [ isDefined(history?.interval) ? this.timewindow.history.interval : null
2023-02-07 17:45:03 +02:00
],
fixedTimewindow: [{
2023-02-09 12:19:40 +02:00
value: isDefined(history?.fixedTimewindow) ? this.timewindow.history.fixedTimewindow : null,
2023-02-07 17:45:03 +02:00
disabled: hideInterval
}],
quickInterval: [{
2023-02-09 12:19:40 +02:00
value: isDefined(history?.quickInterval) ? this.timewindow.history.quickInterval : null,
2023-02-07 17:45:03 +02:00
disabled: hideInterval
}]
}),
aggregation: this.fb.group({
type: [{
2023-02-09 12:19:40 +02:00
value: isDefined(aggregation?.type) ? this.timewindow.aggregation.type : null,
2023-02-07 17:45:03 +02:00
disabled: hideAggregation
}],
limit: [{
2023-02-09 12:19:40 +02:00
value: isDefined(aggregation?.limit) ? this.checkLimit(this.timewindow.aggregation.limit) : null,
2023-02-07 17:45:03 +02:00
disabled: hideAggInterval
}, []]
}),
timezone: [{
value: isDefined(this.timewindow.timezone) ? this.timewindow.timezone : null,
disabled: hideTimezone
}]
2019-08-12 19:34:23 +03:00
});
this.updateValidators(this.timewindowForm.get('aggregation.type').value);
this.timewindowForm.get('aggregation.type').valueChanges.subscribe((aggregationType: AggregationType) => {
this.updateValidators(aggregationType);
});
}
private checkLimit(limit?: number): number {
if (!limit || limit < this.minDatapointsLimit()) {
return this.minDatapointsLimit();
} else if (limit > this.maxDatapointsLimit()) {
return this.maxDatapointsLimit();
}
return limit;
}
private updateValidators(aggType: AggregationType) {
if (aggType !== AggregationType.NONE) {
this.timewindowForm.get('aggregation.limit').clearValidators();
} else {
this.timewindowForm.get('aggregation.limit').setValidators([Validators.min(this.minDatapointsLimit()),
Validators.max(this.maxDatapointsLimit())]);
}
this.timewindowForm.get('aggregation.limit').updateValueAndValidity({emitEvent: false});
2019-08-12 19:34:23 +03:00
}
onTimewindowTypeChange() {
this.timewindowForm.markAsDirty();
const timewindowFormValue = this.timewindowForm.getRawValue();
if (this.timewindow.selectedTab === TimewindowType.REALTIME) {
this.timewindowForm.get('realtime').patchValue({
realtimeType: Object.keys(RealtimeWindowType).includes(HistoryWindowType[timewindowFormValue.history.historyType]) ?
RealtimeWindowType[HistoryWindowType[timewindowFormValue.history.historyType]] :
timewindowFormValue.realtime.realtimeType,
timewindowMs: timewindowFormValue.history.timewindowMs,
quickInterval: Object.values(QuickTimeInterval).filter(interval => interval.startsWith('CURRENT_'))
.includes(QuickTimeInterval[timewindowFormValue.history.quickInterval]) ? timewindowFormValue.history.quickInterval :
timewindowFormValue.realtime.quickInterval
});
setTimeout(() => this.timewindowForm.get('realtime.interval').patchValue(timewindowFormValue.history.interval));
} else {
this.timewindowForm.get('history').patchValue({
historyType: HistoryWindowType[RealtimeWindowType[timewindowFormValue.realtime.realtimeType]],
timewindowMs: timewindowFormValue.realtime.timewindowMs,
quickInterval: timewindowFormValue.realtime.quickInterval
});
setTimeout(() => this.timewindowForm.get('history.interval').patchValue(timewindowFormValue.realtime.interval));
}
this.timewindowForm.patchValue({
aggregation: {
type: timewindowFormValue.aggregation.type,
limit: timewindowFormValue.aggregation.limit
},
timezone: timewindowFormValue.timezone
});
}
2019-08-12 19:34:23 +03:00
update() {
2020-02-25 19:11:25 +02:00
const timewindowFormValue = this.timewindowForm.getRawValue();
2019-09-10 15:12:10 +03:00
this.timewindow.realtime = {
realtimeType: timewindowFormValue.realtime.realtimeType,
2019-09-10 15:12:10 +03:00
timewindowMs: timewindowFormValue.realtime.timewindowMs,
quickInterval: timewindowFormValue.realtime.quickInterval,
2019-09-10 15:12:10 +03:00
interval: timewindowFormValue.realtime.interval
};
this.timewindow.history = {
historyType: timewindowFormValue.history.historyType,
timewindowMs: timewindowFormValue.history.timewindowMs,
interval: timewindowFormValue.history.interval,
fixedTimewindow: timewindowFormValue.history.fixedTimewindow,
2021-03-17 18:38:57 +02:00
quickInterval: timewindowFormValue.history.quickInterval,
2019-09-10 15:12:10 +03:00
};
2019-08-12 19:34:23 +03:00
if (this.aggregation) {
2019-09-10 15:12:10 +03:00
this.timewindow.aggregation = {
type: timewindowFormValue.aggregation.type,
limit: timewindowFormValue.aggregation.limit
};
2019-08-12 19:34:23 +03:00
}
2021-03-17 18:38:57 +02:00
if (this.timezone) {
this.timewindow.timezone = timewindowFormValue.timezone;
}
2019-08-12 19:34:23 +03:00
this.result = this.timewindow;
2023-02-09 12:19:40 +02:00
this.overlayRef.dispose();
2019-08-12 19:34:23 +03:00
}
2023-02-09 12:19:40 +02:00
cancel() {
this.overlayRef.dispose();
2019-08-12 19:34:23 +03:00
}
minDatapointsLimit() {
return this.timeService.getMinDatapointsLimit();
}
maxDatapointsLimit() {
return this.timeService.getMaxDatapointsLimit();
}
minRealtimeAggInterval() {
return this.timeService.minIntervalLimit(this.currentRealtimeTimewindow());
2019-08-12 19:34:23 +03:00
}
maxRealtimeAggInterval() {
return this.timeService.maxIntervalLimit(this.currentRealtimeTimewindow());
}
currentRealtimeTimewindow(): number {
const timeWindowFormValue = this.timewindowForm.getRawValue();
switch (timeWindowFormValue.realtime.realtimeType) {
case RealtimeWindowType.LAST_INTERVAL:
return timeWindowFormValue.realtime.timewindowMs;
case RealtimeWindowType.INTERVAL:
return quickTimeIntervalPeriod(timeWindowFormValue.realtime.quickInterval);
default:
return DAY;
}
2019-08-12 19:34:23 +03:00
}
minHistoryAggInterval() {
return this.timeService.minIntervalLimit(this.currentHistoryTimewindow());
}
maxHistoryAggInterval() {
return this.timeService.maxIntervalLimit(this.currentHistoryTimewindow());
}
currentHistoryTimewindow() {
2020-02-25 19:11:25 +02:00
const timewindowFormValue = this.timewindowForm.getRawValue();
2019-08-12 19:34:23 +03:00
if (timewindowFormValue.history.historyType === HistoryWindowType.LAST_INTERVAL) {
return timewindowFormValue.history.timewindowMs;
} else if (timewindowFormValue.history.historyType === HistoryWindowType.INTERVAL) {
return quickTimeIntervalPeriod(timewindowFormValue.history.quickInterval);
2020-02-28 19:49:14 +02:00
} else if (timewindowFormValue.history.fixedTimewindow) {
2019-08-12 19:34:23 +03:00
return timewindowFormValue.history.fixedTimewindow.endTimeMs -
timewindowFormValue.history.fixedTimewindow.startTimeMs;
2020-02-28 19:49:14 +02:00
} else {
return DAY;
2019-08-12 19:34:23 +03:00
}
}
2020-02-25 19:11:25 +02:00
onHideIntervalChanged() {
if (this.timewindow.hideInterval) {
2020-06-11 10:09:14 +03:00
this.timewindowForm.get('history.historyType').disable({emitEvent: false});
this.timewindowForm.get('history.timewindowMs').disable({emitEvent: false});
this.timewindowForm.get('history.fixedTimewindow').disable({emitEvent: false});
this.timewindowForm.get('history.quickInterval').disable({emitEvent: false});
this.timewindowForm.get('realtime.realtimeType').disable({emitEvent: false});
this.timewindowForm.get('realtime.timewindowMs').disable({emitEvent: false});
this.timewindowForm.get('realtime.quickInterval').disable({emitEvent: false});
2020-02-25 19:11:25 +02:00
} else {
2020-06-11 10:09:14 +03:00
this.timewindowForm.get('history.historyType').enable({emitEvent: false});
this.timewindowForm.get('history.timewindowMs').enable({emitEvent: false});
this.timewindowForm.get('history.fixedTimewindow').enable({emitEvent: false});
this.timewindowForm.get('history.quickInterval').enable({emitEvent: false});
this.timewindowForm.get('realtime.realtimeType').enable({emitEvent: false});
if (!this.timewindow.hideLastInterval) {
this.timewindowForm.get('realtime.timewindowMs').enable({emitEvent: false});
}
if (!this.timewindow.hideQuickInterval) {
this.timewindowForm.get('realtime.quickInterval').enable({emitEvent: false});
}
}
this.timewindowForm.markAsDirty();
}
onHideLastIntervalChanged() {
if (this.timewindow.hideLastInterval) {
this.timewindowForm.get('realtime.timewindowMs').disable({emitEvent: false});
if (!this.timewindow.hideQuickInterval) {
this.timewindowForm.get('realtime.realtimeType').setValue(RealtimeWindowType.INTERVAL);
}
} else {
if (!this.timewindow.hideInterval) {
this.timewindowForm.get('realtime.timewindowMs').enable({emitEvent: false});
}
}
this.timewindowForm.markAsDirty();
}
onHideQuickIntervalChanged() {
if (this.timewindow.hideQuickInterval) {
this.timewindowForm.get('realtime.quickInterval').disable({emitEvent: false});
if (!this.timewindow.hideLastInterval) {
this.timewindowForm.get('realtime.realtimeType').setValue(RealtimeWindowType.LAST_INTERVAL);
}
} else {
if (!this.timewindow.hideInterval) {
this.timewindowForm.get('realtime.quickInterval').enable({emitEvent: false});
}
2020-02-25 19:11:25 +02:00
}
this.timewindowForm.markAsDirty();
}
onHideAggregationChanged() {
if (this.timewindow.hideAggregation) {
2020-06-11 10:09:14 +03:00
this.timewindowForm.get('aggregation.type').disable({emitEvent: false});
2020-02-25 19:11:25 +02:00
} else {
2020-06-11 10:09:14 +03:00
this.timewindowForm.get('aggregation.type').enable({emitEvent: false});
2020-02-25 19:11:25 +02:00
}
this.timewindowForm.markAsDirty();
}
onHideAggIntervalChanged() {
if (this.timewindow.hideAggInterval) {
2020-06-11 10:09:14 +03:00
this.timewindowForm.get('aggregation.limit').disable({emitEvent: false});
2020-02-25 19:11:25 +02:00
} else {
2020-06-11 10:09:14 +03:00
this.timewindowForm.get('aggregation.limit').enable({emitEvent: false});
2020-02-25 19:11:25 +02:00
}
this.timewindowForm.markAsDirty();
}
2021-03-17 18:38:57 +02:00
onHideTimezoneChanged() {
if (this.timewindow.hideTimezone) {
this.timewindowForm.get('timezone').disable({emitEvent: false});
} else {
this.timewindowForm.get('timezone').enable({emitEvent: false});
}
this.timewindowForm.markAsDirty();
}
2019-08-12 19:34:23 +03:00
}