Timewindow: apply default grouping interval option for interval
This commit is contained in:
parent
7277a0939c
commit
7aae331ac4
@ -337,7 +337,6 @@ import * as DatapointsLimitComponent from '@shared/components/time/datapoints-li
|
|||||||
import * as AggregationTypeSelectComponent from '@shared/components/time/aggregation/aggregation-type-select.component';
|
import * as AggregationTypeSelectComponent from '@shared/components/time/aggregation/aggregation-type-select.component';
|
||||||
import * as AggregationOptionsConfigComponent from '@shared/components/time/aggregation/aggregation-options-config-panel.component';
|
import * as AggregationOptionsConfigComponent from '@shared/components/time/aggregation/aggregation-options-config-panel.component';
|
||||||
import * as IntervalOptionsConfigPanelComponent from '@shared/components/time/interval-options-config-panel.component';
|
import * as IntervalOptionsConfigPanelComponent from '@shared/components/time/interval-options-config-panel.component';
|
||||||
import * as TimeIntervalsListComponent from '@shared/components/time/time-intervals-list.component';
|
|
||||||
|
|
||||||
import { IModulesMap } from '@modules/common/modules-map.models';
|
import { IModulesMap } from '@modules/common/modules-map.models';
|
||||||
import { Observable, map, of } from 'rxjs';
|
import { Observable, map, of } from 'rxjs';
|
||||||
@ -478,7 +477,6 @@ class ModulesMap implements IModulesMap {
|
|||||||
'@shared/components/time/aggregation/aggregation-type-select.component': AggregationTypeSelectComponent,
|
'@shared/components/time/aggregation/aggregation-type-select.component': AggregationTypeSelectComponent,
|
||||||
'@shared/components/time/aggregation/aggregation-options-config-panel.component': AggregationOptionsConfigComponent,
|
'@shared/components/time/aggregation/aggregation-options-config-panel.component': AggregationOptionsConfigComponent,
|
||||||
'@shared/components/time/interval-options-config-panel.component': IntervalOptionsConfigPanelComponent,
|
'@shared/components/time/interval-options-config-panel.component': IntervalOptionsConfigPanelComponent,
|
||||||
'@shared/components/time/time-intervals-list.component': TimeIntervalsListComponent,
|
|
||||||
'@shared/components/value-input.component': ValueInputComponent,
|
'@shared/components/value-input.component': ValueInputComponent,
|
||||||
'@shared/components/dashboard-autocomplete.component': DashboardAutocompleteComponent,
|
'@shared/components/dashboard-autocomplete.component': DashboardAutocompleteComponent,
|
||||||
'@shared/components/entity/entity-subtype-autocomplete.component': EntitySubTypeAutocompleteComponent,
|
'@shared/components/entity/entity-subtype-autocomplete.component': EntitySubTypeAutocompleteComponent,
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
<!--
|
||||||
|
|
||||||
|
Copyright © 2016-2024 The Thingsboard Authors
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<section class="flex flex-1 flex-row gap-2" [formGroup]="timeintervalFormGroup">
|
||||||
|
<mat-form-field class="flex flex-1" [class]="{'tb-inline-field': appearance === 'outline'}"
|
||||||
|
[subscriptSizing]="subscriptSizing" [appearance]="appearance">
|
||||||
|
<mat-select formControlName="aggIntervals" multiple
|
||||||
|
placeholder="{{ 'timewindow.all' | translate }}">
|
||||||
|
<mat-option *ngFor="let interval of allIntervals" [value]="interval.value">
|
||||||
|
{{ interval.name | translate:interval.translateParams }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field class="flex flex-1" [class]="{'tb-inline-field': appearance === 'outline'}"
|
||||||
|
[subscriptSizing]="subscriptSizing" [appearance]="appearance">
|
||||||
|
<mat-select formControlName="defaultAggInterval"
|
||||||
|
placeholder="{{ 'action.set' | translate }}">
|
||||||
|
<mat-option *ngFor="let interval of selectedIntervals" [value]="interval.value">
|
||||||
|
{{ interval.name | translate:interval.translateParams }}
|
||||||
|
</mat-option>
|
||||||
|
</mat-select>
|
||||||
|
</mat-form-field>
|
||||||
|
</section>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
@import '../../../../scss/constants';
|
@import '../../../../../scss/constants';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
|
|
||||||
@ -19,23 +19,28 @@ import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from
|
|||||||
import { TimeService } from '@core/services/time.service';
|
import { TimeService } from '@core/services/time.service';
|
||||||
import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field';
|
import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field';
|
||||||
import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
|
import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
|
||||||
import { Interval, TimeInterval } from '@shared/models/time/time.models';
|
import {
|
||||||
|
Interval,
|
||||||
|
intervalValuesToTimeIntervals,
|
||||||
|
TimeInterval,
|
||||||
|
TimewindowAggIntervalOptions
|
||||||
|
} from '@shared/models/time/time.models';
|
||||||
import { isDefined } from '@core/utils';
|
import { isDefined } from '@core/utils';
|
||||||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'tb-time-intervals-list',
|
selector: 'tb-grouping-interval-options',
|
||||||
templateUrl: './time-intervals-list.component.html',
|
templateUrl: './grouping-interval-options.component.html',
|
||||||
styleUrls: ['./time-intervals-list.component.scss'],
|
styleUrls: ['./grouping-interval-options.component.scss'],
|
||||||
providers: [
|
providers: [
|
||||||
{
|
{
|
||||||
provide: NG_VALUE_ACCESSOR,
|
provide: NG_VALUE_ACCESSOR,
|
||||||
useExisting: forwardRef(() => TimeIntervalsListComponent),
|
useExisting: forwardRef(() => GroupingIntervalOptionsComponent),
|
||||||
multi: true
|
multi: true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class TimeIntervalsListComponent implements OnInit, ControlValueAccessor {
|
export class GroupingIntervalOptionsComponent implements OnInit, ControlValueAccessor {
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
@coerceNumber()
|
@coerceNumber()
|
||||||
@ -45,16 +50,6 @@ export class TimeIntervalsListComponent implements OnInit, ControlValueAccessor
|
|||||||
@coerceNumber()
|
@coerceNumber()
|
||||||
max: number;
|
max: number;
|
||||||
|
|
||||||
@Input() predefinedName: string;
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
@coerceBoolean()
|
|
||||||
setAllIfEmpty = false;
|
|
||||||
|
|
||||||
@Input()
|
|
||||||
@coerceBoolean()
|
|
||||||
returnEmptyIfAllSet = false;
|
|
||||||
|
|
||||||
@Input()
|
@Input()
|
||||||
@coerceBoolean()
|
@coerceBoolean()
|
||||||
useCalendarIntervals = false;
|
useCalendarIntervals = false;
|
||||||
@ -69,10 +64,11 @@ export class TimeIntervalsListComponent implements OnInit, ControlValueAccessor
|
|||||||
|
|
||||||
allIntervals: Array<TimeInterval>;
|
allIntervals: Array<TimeInterval>;
|
||||||
allIntervalValues: Array<Interval>;
|
allIntervalValues: Array<Interval>;
|
||||||
|
selectedIntervals: Array<TimeInterval>;
|
||||||
|
|
||||||
timeintervalFormGroup: FormGroup;
|
timeintervalFormGroup: FormGroup;
|
||||||
|
|
||||||
private modelValue: Array<Interval>;
|
private modelValue: TimewindowAggIntervalOptions;
|
||||||
private rendered = false;
|
private rendered = false;
|
||||||
private propagateChangeValue: any;
|
private propagateChangeValue: any;
|
||||||
|
|
||||||
@ -83,9 +79,13 @@ export class TimeIntervalsListComponent implements OnInit, ControlValueAccessor
|
|||||||
constructor(private timeService: TimeService,
|
constructor(private timeService: TimeService,
|
||||||
private fb: FormBuilder) {
|
private fb: FormBuilder) {
|
||||||
this.timeintervalFormGroup = this.fb.group({
|
this.timeintervalFormGroup = this.fb.group({
|
||||||
intervals: [ [] ]
|
aggIntervals: [ [] ],
|
||||||
|
defaultAggInterval: [ null ],
|
||||||
});
|
});
|
||||||
this.timeintervalFormGroup.get('intervals').valueChanges.pipe(
|
this.timeintervalFormGroup.get('aggIntervals').valueChanges.pipe(
|
||||||
|
takeUntilDestroyed()
|
||||||
|
).subscribe(selectedIntervalValues => this.setSelectedIntervals(selectedIntervalValues));
|
||||||
|
this.timeintervalFormGroup.valueChanges.pipe(
|
||||||
takeUntilDestroyed()
|
takeUntilDestroyed()
|
||||||
).subscribe(() => this.updateView());
|
).subscribe(() => this.updateView());
|
||||||
}
|
}
|
||||||
@ -113,10 +113,11 @@ export class TimeIntervalsListComponent implements OnInit, ControlValueAccessor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeValue(intervals: Array<Interval>): void {
|
writeValue(intervalOptions: TimewindowAggIntervalOptions): void {
|
||||||
this.modelValue = intervals;
|
this.modelValue = intervalOptions;
|
||||||
this.rendered = true;
|
this.rendered = true;
|
||||||
this.setIntervals(this.modelValue);
|
this.timeintervalFormGroup.get('defaultAggInterval').patchValue(intervalOptions.defaultAggInterval, { emitEvent: false });
|
||||||
|
this.setIntervals(intervalOptions.aggIntervals);
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateIntervalsList() {
|
private updateIntervalsList() {
|
||||||
@ -125,24 +126,41 @@ export class TimeIntervalsListComponent implements OnInit, ControlValueAccessor
|
|||||||
}
|
}
|
||||||
|
|
||||||
private setIntervals(intervals: Array<Interval>) {
|
private setIntervals(intervals: Array<Interval>) {
|
||||||
this.timeintervalFormGroup.get('intervals').patchValue(
|
const selectedIntervals = !intervals?.length ? this.allIntervalValues : intervals;
|
||||||
(this.setAllIfEmpty && !intervals?.length) ? this.allIntervalValues : intervals,
|
this.timeintervalFormGroup.get('aggIntervals').patchValue(
|
||||||
|
selectedIntervals,
|
||||||
{emitEvent: false});
|
{emitEvent: false});
|
||||||
|
this.setSelectedIntervals(selectedIntervals);
|
||||||
|
}
|
||||||
|
|
||||||
|
private setSelectedIntervals(selectedIntervalValues: Array<Interval>) {
|
||||||
|
if (!selectedIntervalValues.length || selectedIntervalValues.length === this.allIntervalValues.length) {
|
||||||
|
this.selectedIntervals = this.allIntervals;
|
||||||
|
} else {
|
||||||
|
this.selectedIntervals = intervalValuesToTimeIntervals(selectedIntervalValues);
|
||||||
|
}
|
||||||
|
const defaultInterval: Interval = this.timeintervalFormGroup.get('defaultAggInterval').value;
|
||||||
|
if (defaultInterval && !selectedIntervalValues.includes(defaultInterval)) {
|
||||||
|
this.timeintervalFormGroup.get('defaultAggInterval').patchValue(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private updateView() {
|
private updateView() {
|
||||||
if (!this.rendered) {
|
if (!this.rendered) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let value: Array<Interval>;
|
let selectedIntervals: Array<Interval>;
|
||||||
const intervals: Array<Interval> = this.timeintervalFormGroup.get('intervals').value;
|
const intervals: Array<Interval> = this.timeintervalFormGroup.get('aggIntervals').value;
|
||||||
|
|
||||||
if (!this.returnEmptyIfAllSet || intervals.length < this.allIntervals.length) {
|
if (intervals.length < this.allIntervals.length) {
|
||||||
value = intervals;
|
selectedIntervals = intervals;
|
||||||
} else {
|
} else {
|
||||||
value = [];
|
selectedIntervals = [];
|
||||||
}
|
}
|
||||||
this.modelValue = value;
|
this.modelValue = {
|
||||||
|
aggIntervals: selectedIntervals,
|
||||||
|
defaultAggInterval: this.timeintervalFormGroup.get('defaultAggInterval').value
|
||||||
|
};
|
||||||
this.propagateChange(this.modelValue);
|
this.propagateChange(this.modelValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,8 +25,8 @@
|
|||||||
<div class="tb-form-table-header">
|
<div class="tb-form-table-header">
|
||||||
<div class="tb-form-table-header-cell tb-interval">{{"timewindow.interval" | translate }}</div>
|
<div class="tb-form-table-header-cell tb-interval">{{"timewindow.interval" | translate }}</div>
|
||||||
<ng-container *ngIf="aggregation">
|
<ng-container *ngIf="aggregation">
|
||||||
<div class="tb-form-table-header-cell tb-agg-interval">{{"timewindow.allowed-agg-intervals" | translate }}</div>
|
<div class="tb-form-table-header-cell tb-agg-interval-header">{{"timewindow.allowed-agg-intervals" | translate }}</div>
|
||||||
<div class="tb-form-table-header-cell tb-agg-interval">{{"timewindow.default-agg-interval" | translate }}</div>
|
<div class="tb-form-table-header-cell tb-agg-interval-header">{{"timewindow.default-agg-interval" | translate }}</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div class="tb-form-table-body" formArrayName="intervals">
|
<div class="tb-form-table-body" formArrayName="intervals">
|
||||||
@ -39,29 +39,15 @@
|
|||||||
</div>
|
</div>
|
||||||
<ng-container *ngIf="aggregation">
|
<ng-container *ngIf="aggregation">
|
||||||
<div class="tb-form-table-row-cell tb-agg-interval">
|
<div class="tb-form-table-row-cell tb-agg-interval">
|
||||||
<tb-time-intervals-list
|
<tb-grouping-interval-options
|
||||||
class="tb-inline-field"
|
class="tb-inline-field"
|
||||||
formControlName="aggIntervals"
|
formControlName="aggIntervalsConfig"
|
||||||
[min]="minAggInterval(interval.get('value').value)"
|
[min]="minAggInterval(interval.get('value').value)"
|
||||||
[max]="maxAggInterval(interval.get('value').value)"
|
[max]="maxAggInterval(interval.get('value').value)"
|
||||||
useCalendarIntervals
|
useCalendarIntervals
|
||||||
subscriptSizing="dynamic"
|
subscriptSizing="dynamic"
|
||||||
appearance="outline"
|
appearance="outline">
|
||||||
setAllIfEmpty
|
</tb-grouping-interval-options>
|
||||||
returnEmptyIfAllSet>
|
|
||||||
</tb-time-intervals-list>
|
|
||||||
</div>
|
|
||||||
<div class="tb-form-table-row-cell tb-agg-interval">
|
|
||||||
<tb-timeinterval
|
|
||||||
class="tb-inline-field"
|
|
||||||
formControlName="defaultAggInterval"
|
|
||||||
[min]="minAggInterval(interval.get('value').value)"
|
|
||||||
[max]="maxAggInterval(interval.get('value').value)"
|
|
||||||
useCalendarIntervals
|
|
||||||
subscriptSizing="dynamic"
|
|
||||||
appearance="outline"
|
|
||||||
disabledAdvanced>
|
|
||||||
</tb-timeinterval>
|
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -30,12 +30,16 @@
|
|||||||
flex: 1 1 30%;
|
flex: 1 1 30%;
|
||||||
}
|
}
|
||||||
&.tb-agg-interval {
|
&.tb-agg-interval {
|
||||||
flex: 1 1 35%;
|
flex: 1 1 70%;
|
||||||
width: 35%;
|
width: 70%;
|
||||||
max-width: 35%;
|
max-width: 70%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tb-form-table-header-cell.tb-agg-interval-header {
|
||||||
|
flex: 1 1 35%;
|
||||||
|
}
|
||||||
|
|
||||||
.tb-form-hint {
|
.tb-form-hint {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -100,26 +100,26 @@ export class IntervalOptionsConfigPanelComponent implements OnInit {
|
|||||||
const intervalControls: Array<AbstractControl> = [];
|
const intervalControls: Array<AbstractControl> = [];
|
||||||
for (const interval of this.allIntervals) {
|
for (const interval of this.allIntervals) {
|
||||||
const intervalConfig: TimewindowAggIntervalOptions = this.aggIntervalsConfig?.hasOwnProperty(interval.value)
|
const intervalConfig: TimewindowAggIntervalOptions = this.aggIntervalsConfig?.hasOwnProperty(interval.value)
|
||||||
? this.allIntervalValues[interval.value]
|
? this.aggIntervalsConfig[interval.value]
|
||||||
: null;
|
: null;
|
||||||
const intervalEnabled = this.allowedIntervals?.length ? this.allowedIntervals.includes(interval.value) : true;
|
const intervalEnabled = this.allowedIntervals?.length ? this.allowedIntervals.includes(interval.value) : false;
|
||||||
const intervalControl = this.fb.group({
|
const intervalControl = this.fb.group({
|
||||||
name: [this.translate.instant(interval.name, interval.translateParams)],
|
name: [this.translate.instant(interval.name, interval.translateParams)],
|
||||||
value: [interval.value],
|
value: [interval.value],
|
||||||
enabled: [intervalEnabled],
|
enabled: [intervalEnabled],
|
||||||
aggIntervals: [{value: intervalConfig ? intervalConfig.aggIntervals : [], disabled: !(intervalEnabled && this.aggregation)}],
|
aggIntervalsConfig: [{value: {
|
||||||
defaultAggInterval: [{value: intervalConfig ? intervalConfig.defaultAggInterval : null, disabled: !(intervalEnabled && this.aggregation)}],
|
aggIntervals: intervalConfig?.aggIntervals ? intervalConfig.aggIntervals : [],
|
||||||
|
defaultAggInterval: intervalConfig?.defaultAggInterval ? intervalConfig.defaultAggInterval : null
|
||||||
|
}, disabled: !(intervalEnabled && this.aggregation)}]
|
||||||
});
|
});
|
||||||
if (this.aggregation) {
|
if (this.aggregation) {
|
||||||
intervalControl.get('enabled').valueChanges.pipe(
|
intervalControl.get('enabled').valueChanges.pipe(
|
||||||
takeUntilDestroyed(this.destroyRef)
|
takeUntilDestroyed(this.destroyRef)
|
||||||
).subscribe((intervalEnabled) => {
|
).subscribe((intervalEnabled) => {
|
||||||
if (intervalEnabled) {
|
if (intervalEnabled) {
|
||||||
intervalControl.get('aggIntervals').enable({emitEvent: false});
|
intervalControl.get('aggIntervalsConfig').enable({emitEvent: false});
|
||||||
intervalControl.get('defaultAggInterval').enable({emitEvent: false});
|
|
||||||
} else {
|
} else {
|
||||||
intervalControl.get('aggIntervals').disable({emitEvent: false});
|
intervalControl.get('aggIntervalsConfig').disable({emitEvent: false});
|
||||||
intervalControl.get('defaultAggInterval').disable({emitEvent: false});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -160,19 +160,18 @@ export class IntervalOptionsConfigPanelComponent implements OnInit {
|
|||||||
for (const interval of intervalOptionsConfig) {
|
for (const interval of intervalOptionsConfig) {
|
||||||
if (interval.enabled) {
|
if (interval.enabled) {
|
||||||
allowedIntervals.push(interval.value);
|
allowedIntervals.push(interval.value);
|
||||||
if (this.aggregation && (interval.aggIntervals.length || interval.defaultAggInterval)) {
|
if (this.aggregation && (interval.aggIntervalsConfig.aggIntervals.length || interval.aggIntervalsConfig.defaultAggInterval)) {
|
||||||
const intervalParams: TimewindowAggIntervalOptions = {};
|
const intervalParams: TimewindowAggIntervalOptions = {};
|
||||||
if (interval.aggIntervals.length) {
|
if (interval.aggIntervalsConfig.aggIntervals.length) {
|
||||||
intervalParams.aggIntervals = interval.aggIntervals;
|
intervalParams.aggIntervals = interval.aggIntervalsConfig.aggIntervals;
|
||||||
}
|
}
|
||||||
if (interval.defaultAggInterval) {
|
if (interval.aggIntervalsConfig.defaultAggInterval) {
|
||||||
intervalParams.defaultAggInterval = interval.defaultAggInterval;
|
intervalParams.defaultAggInterval = interval.aggIntervalsConfig.defaultAggInterval;
|
||||||
}
|
}
|
||||||
aggIntervalsConfig[interval.value] = intervalParams;
|
aggIntervalsConfig[interval.value] = intervalParams;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(aggIntervalsConfig);
|
|
||||||
this.onClose({
|
this.onClose({
|
||||||
// if full list selected returns empty for optimization
|
// if full list selected returns empty for optimization
|
||||||
allowedIntervals: allowedIntervals?.length < this.allIntervals.length ? allowedIntervals : [],
|
allowedIntervals: allowedIntervals?.length < this.allIntervals.length ? allowedIntervals : [],
|
||||||
@ -192,8 +191,10 @@ export class IntervalOptionsConfigPanelComponent implements OnInit {
|
|||||||
for (const interval of intervalControls) {
|
for (const interval of intervalControls) {
|
||||||
interval.patchValue({
|
interval.patchValue({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
aggIntervals: [],
|
aggIntervalsConfig: {
|
||||||
defaultAggInterval: null,
|
aggIntervals: [],
|
||||||
|
defaultAggInterval: null
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
this.intervalOptionsConfigForm.markAsDirty();
|
this.intervalOptionsConfigForm.markAsDirty();
|
||||||
|
|||||||
@ -1,27 +0,0 @@
|
|||||||
<!--
|
|
||||||
|
|
||||||
Copyright © 2016-2024 The Thingsboard Authors
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<section class="flex flex-1 flex-row" [formGroup]="timeintervalFormGroup">
|
|
||||||
<mat-form-field class="flex flex-1" [subscriptSizing]="subscriptSizing" [appearance]="appearance">
|
|
||||||
<mat-label *ngIf="predefinedName" translate>{{ predefinedName }}</mat-label>
|
|
||||||
<mat-select formControlName="intervals" multiple>
|
|
||||||
<mat-option *ngFor="let interval of allIntervals" [value]="interval.value">
|
|
||||||
{{ interval.name | translate:interval.translateParams }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-select>
|
|
||||||
</mat-form-field>
|
|
||||||
</section>
|
|
||||||
@ -26,7 +26,7 @@ import {
|
|||||||
realtimeAllowedAggIntervals,
|
realtimeAllowedAggIntervals,
|
||||||
RealtimeWindowType,
|
RealtimeWindowType,
|
||||||
realtimeWindowTypeTranslations,
|
realtimeWindowTypeTranslations,
|
||||||
Timewindow,
|
Timewindow, TimewindowAggIntervalsConfig,
|
||||||
TimewindowType,
|
TimewindowType,
|
||||||
updateFormValuesOnTimewindowTypeChange
|
updateFormValuesOnTimewindowTypeChange
|
||||||
} from '@shared/models/time/time.models';
|
} from '@shared/models/time/time.models';
|
||||||
@ -235,6 +235,55 @@ export class TimewindowConfigDialogComponent extends PageComponent implements On
|
|||||||
? this.timewindow.hideTimezone : false ]
|
? this.timewindow.hideTimezone : false ]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.timewindowForm.get('realtime.timewindowMs').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((timewindowMs: number) => {
|
||||||
|
const lastAggIntervalsConfig:TimewindowAggIntervalsConfig =
|
||||||
|
this.timewindowForm.get('realtime.advancedParams.lastAggIntervalsConfig').value;
|
||||||
|
if (lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) &&
|
||||||
|
lastAggIntervalsConfig[timewindowMs].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('realtime.interval').patchValue(
|
||||||
|
lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.timewindowForm.get('realtime.quickInterval').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((quickInterval: number) => {
|
||||||
|
const quickAggIntervalsConfig:TimewindowAggIntervalsConfig =
|
||||||
|
this.timewindowForm.get('realtime.advancedParams.quickAggIntervalsConfig').value;
|
||||||
|
if (quickAggIntervalsConfig?.hasOwnProperty(quickInterval) &&
|
||||||
|
quickAggIntervalsConfig[quickInterval].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('realtime.interval').patchValue(
|
||||||
|
quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.timewindowForm.get('history.timewindowMs').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((timewindowMs: number) => {
|
||||||
|
const lastAggIntervalsConfig:TimewindowAggIntervalsConfig =
|
||||||
|
this.timewindowForm.get('history.advancedParams.lastAggIntervalsConfig').value;
|
||||||
|
if (lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) &&
|
||||||
|
lastAggIntervalsConfig[timewindowMs].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('history.interval').patchValue(
|
||||||
|
lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.timewindowForm.get('history.quickInterval').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((quickInterval: number) => {
|
||||||
|
const quickAggIntervalsConfig:TimewindowAggIntervalsConfig =
|
||||||
|
this.timewindowForm.get('history.advancedParams.quickAggIntervalsConfig').value;
|
||||||
|
if (quickAggIntervalsConfig?.hasOwnProperty(quickInterval) &&
|
||||||
|
quickAggIntervalsConfig[quickInterval].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('history.interval').patchValue(
|
||||||
|
quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.updateValidators(this.timewindowForm.get('aggregation.type').value);
|
this.updateValidators(this.timewindowForm.get('aggregation.type').value);
|
||||||
this.timewindowForm.get('aggregation.type').valueChanges.pipe(
|
this.timewindowForm.get('aggregation.type').valueChanges.pipe(
|
||||||
takeUntil(this.destroy$)
|
takeUntil(this.destroy$)
|
||||||
|
|||||||
@ -298,6 +298,48 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit, O
|
|||||||
disabled: hideTimezone
|
disabled: hideTimezone
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.timewindowForm.get('realtime.timewindowMs').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((timewindowMs: number) => {
|
||||||
|
if (this.realtimeAdvancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) &&
|
||||||
|
this.realtimeAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('realtime.interval').patchValue(
|
||||||
|
this.realtimeAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.timewindowForm.get('realtime.quickInterval').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((quickInterval: number) => {
|
||||||
|
if (this.realtimeAdvancedParams?.quickAggIntervalsConfig?.hasOwnProperty(quickInterval) &&
|
||||||
|
this.realtimeAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('realtime.interval').patchValue(
|
||||||
|
this.realtimeAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.timewindowForm.get('history.timewindowMs').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((timewindowMs: number) => {
|
||||||
|
if (this.historyAdvancedParams?.lastAggIntervalsConfig?.hasOwnProperty(timewindowMs) &&
|
||||||
|
this.historyAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('history.interval').patchValue(
|
||||||
|
this.historyAdvancedParams.lastAggIntervalsConfig[timewindowMs].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.timewindowForm.get('history.quickInterval').valueChanges.pipe(
|
||||||
|
takeUntil(this.destroy$)
|
||||||
|
).subscribe((quickInterval: number) => {
|
||||||
|
if (this.historyAdvancedParams?.quickAggIntervalsConfig?.hasOwnProperty(quickInterval) &&
|
||||||
|
this.historyAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval) {
|
||||||
|
this.timewindowForm.get('history.interval').patchValue(
|
||||||
|
this.historyAdvancedParams.quickAggIntervalsConfig[quickInterval].defaultAggInterval, {emitEvent: false}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.updateValidators(this.timewindowForm.get('aggregation.type').value);
|
this.updateValidators(this.timewindowForm.get('aggregation.type').value);
|
||||||
this.timewindowForm.get('aggregation.type').valueChanges.pipe(
|
this.timewindowForm.get('aggregation.type').valueChanges.pipe(
|
||||||
takeUntil(this.destroy$)
|
takeUntil(this.destroy$)
|
||||||
|
|||||||
@ -221,7 +221,7 @@ import { DatapointsLimitComponent } from '@shared/components/time/datapoints-lim
|
|||||||
import { AggregationTypeSelectComponent } from '@shared/components/time/aggregation/aggregation-type-select.component';
|
import { AggregationTypeSelectComponent } from '@shared/components/time/aggregation/aggregation-type-select.component';
|
||||||
import { AggregationOptionsConfigPanelComponent } from '@shared/components/time/aggregation/aggregation-options-config-panel.component';
|
import { AggregationOptionsConfigPanelComponent } from '@shared/components/time/aggregation/aggregation-options-config-panel.component';
|
||||||
import { IntervalOptionsConfigPanelComponent } from '@shared/components/time/interval-options-config-panel.component';
|
import { IntervalOptionsConfigPanelComponent } from '@shared/components/time/interval-options-config-panel.component';
|
||||||
import { TimeIntervalsListComponent } from '@shared/components/time/time-intervals-list.component';
|
import { GroupingIntervalOptionsComponent } from '@shared/components/time/aggregation/grouping-interval-options.component';
|
||||||
|
|
||||||
export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) {
|
export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) {
|
||||||
return markedOptionsService;
|
return markedOptionsService;
|
||||||
@ -307,7 +307,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
|
|||||||
TimewindowPanelComponent,
|
TimewindowPanelComponent,
|
||||||
TimewindowConfigDialogComponent,
|
TimewindowConfigDialogComponent,
|
||||||
TimeintervalComponent,
|
TimeintervalComponent,
|
||||||
TimeIntervalsListComponent,
|
GroupingIntervalOptionsComponent,
|
||||||
TimezoneComponent,
|
TimezoneComponent,
|
||||||
TimezonePanelComponent,
|
TimezonePanelComponent,
|
||||||
QuickTimeIntervalComponent,
|
QuickTimeIntervalComponent,
|
||||||
@ -518,7 +518,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
|
|||||||
TimewindowPanelComponent,
|
TimewindowPanelComponent,
|
||||||
TimewindowConfigDialogComponent,
|
TimewindowConfigDialogComponent,
|
||||||
TimeintervalComponent,
|
TimeintervalComponent,
|
||||||
TimeIntervalsListComponent,
|
GroupingIntervalOptionsComponent,
|
||||||
TimezoneComponent,
|
TimezoneComponent,
|
||||||
TimezonePanelComponent,
|
TimezonePanelComponent,
|
||||||
QuickTimeIntervalComponent,
|
QuickTimeIntervalComponent,
|
||||||
|
|||||||
@ -80,7 +80,8 @@
|
|||||||
"clear": "Clear",
|
"clear": "Clear",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"delete-anyway": "Delete anyway",
|
"delete-anyway": "Delete anyway",
|
||||||
"delete-selected": "Delete selected"
|
"delete-selected": "Delete selected",
|
||||||
|
"set": "Set"
|
||||||
},
|
},
|
||||||
"aggregation": {
|
"aggregation": {
|
||||||
"aggregation": "Aggregation",
|
"aggregation": "Aggregation",
|
||||||
@ -4712,7 +4713,8 @@
|
|||||||
"allowed-agg-intervals": "Allowed grouping intervals",
|
"allowed-agg-intervals": "Allowed grouping intervals",
|
||||||
"default-agg-interval": "Default grouping interval",
|
"default-agg-interval": "Default grouping interval",
|
||||||
"edit-intervals-list-hint": "List of available interval options can be specified.",
|
"edit-intervals-list-hint": "List of available interval options can be specified.",
|
||||||
"edit-grouping-intervals-list-hint": "It is possible to configure the grouping intervals list and default grouping interval."
|
"edit-grouping-intervals-list-hint": "It is possible to configure the grouping intervals list and default grouping interval.",
|
||||||
|
"all": "All"
|
||||||
},
|
},
|
||||||
"tooltip": {
|
"tooltip": {
|
||||||
"trigger": "Trigger",
|
"trigger": "Trigger",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user