diff --git a/ui-ngx/src/app/modules/common/modules-map.ts b/ui-ngx/src/app/modules/common/modules-map.ts
index b5ff3f5f33..b188abbafe 100644
--- a/ui-ngx/src/app/modules/common/modules-map.ts
+++ b/ui-ngx/src/app/modules/common/modules-map.ts
@@ -337,6 +337,7 @@ import * as TimezoneComponent from '@shared/components/time/timezone.component';
import * as TimezonePanelComponent from '@shared/components/time/timezone-panel.component';
import * as DatapointsLimitComponent from '@shared/components/time/datapoints-limit.component';
import * as AggregationTypeSelectComponent from '@shared/components/aggregation/aggregation-type-select.component';
+import * as AggregationOptionsConfigComponent from '@shared/components/aggregation/aggregation-options-config-panel.component';
import { IModulesMap } from '@modules/common/modules-map.models';
@@ -470,8 +471,9 @@ class ModulesMap implements IModulesMap {
'@shared/components/time/timezone-select.component': TimezoneSelectComponent,
'@shared/components/time/timezone.component': TimezoneComponent,
'@shared/components/time/timezone-panel.component': TimezonePanelComponent,
- '@shared/components/time/datapoints-limit': DatapointsLimitComponent,
- '@shared/components/aggregation/aggregation-type-select': AggregationTypeSelectComponent,
+ '@shared/components/time/datapoints-limit.component': DatapointsLimitComponent,
+ '@shared/components/aggregation/aggregation-type-select.component': AggregationTypeSelectComponent,
+ '@shared/components/aggregation/aggregation-options-config-panel.component': AggregationOptionsConfigComponent,
'@shared/components/value-input.component': ValueInputComponent,
'@shared/components/dashboard-autocomplete.component': DashboardAutocompleteComponent,
'@shared/components/entity/entity-subtype-autocomplete.component': EntitySubTypeAutocompleteComponent,
diff --git a/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.html b/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.html
new file mode 100644
index 0000000000..35016c6a28
--- /dev/null
+++ b/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.html
@@ -0,0 +1,24 @@
+
+
+
+
+ {{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}
+
+
+
diff --git a/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.scss b/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.scss
new file mode 100644
index 0000000000..b9dc294716
--- /dev/null
+++ b/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.scss
@@ -0,0 +1,17 @@
+/**
+ * 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.
+ */
+
+
diff --git a/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.ts b/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.ts
new file mode 100644
index 0000000000..1b789a747c
--- /dev/null
+++ b/ui-ngx/src/app/shared/components/aggregation/aggregation-options-config-panel.component.ts
@@ -0,0 +1,72 @@
+///
+/// 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.
+///
+
+import { Component, Input, OnInit } from '@angular/core';
+import { aggregationTranslations, AggregationType } from '@shared/models/time/time.models';
+import { FormBuilder, FormGroup } from '@angular/forms';
+import { TbPopoverComponent } from '@shared/components/popover.component';
+
+export interface AggregationOptionsSelectionResult {
+ allowedAggregationTypes: AggregationType[] | null;
+}
+
+@Component({
+ selector: 'tb-aggregation-options-config-panel',
+ templateUrl: './aggregation-options-config-panel.component.html',
+ styleUrls: ['./aggregation-options-config-panel.component.scss']
+})
+export class AggregationOptionsConfigPanelComponent implements OnInit {
+
+ @Input()
+ allowedAggregationTypes: Array;
+
+ @Input()
+ onClose: (result: AggregationOptionsSelectionResult | null) => void;
+
+ @Input()
+ popoverComponent: TbPopoverComponent;
+
+ aggregationOptionsConfigForm: FormGroup;
+
+ aggregationTypes = AggregationType;
+
+ aggregations = Object.keys(AggregationType);
+
+ aggregationTypesTranslations = aggregationTranslations;
+
+ constructor(private fb: FormBuilder) {}
+
+ ngOnInit(): void {
+ this.aggregationOptionsConfigForm = this.fb.group({
+ allowedAggregationTypes: [this.allowedAggregationTypes]
+ });
+ }
+
+ update() {
+ if (this.onClose) {
+ this.onClose({
+ allowedAggregationTypes: this.aggregationOptionsConfigForm.get('allowedAggregationTypes').value
+ });
+ }
+ }
+
+ cancel() {
+ if (this.onClose) {
+ this.onClose(null);
+ }
+ }
+
+}
diff --git a/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.html b/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.html
index 401ae7f16a..b9a9cdd93e 100644
--- a/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.html
+++ b/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.html
@@ -22,4 +22,7 @@
{{ displayAggregationTypeFn(type) }}
+
+
+
diff --git a/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.scss b/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.scss
index ddc2385dfa..4e08e7fc73 100644
--- a/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.scss
+++ b/ui-ngx/src/app/shared/components/aggregation/aggregation-type-select.component.scss
@@ -26,4 +26,10 @@
.mat-mdc-select-value {
min-width: 100px;
}
+ .mat-mdc-form-field-has-icon-suffix .mat-mdc-text-field-wrapper:has(.mat-mdc-form-field-icon-suffix:empty) {
+ padding-right: 12px;
+ }
+ .mat-mdc-form-field-icon-suffix:empty {
+ padding: 0;
+ }
}
diff --git a/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.html b/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.html
index 69ce692403..dbfb9e37ea 100644
--- a/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.html
+++ b/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.html
@@ -169,6 +169,10 @@
+
diff --git a/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts b/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts
index 6eda855cb5..f99dd02bf2 100644
--- a/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts
+++ b/ui-ngx/src/app/shared/components/time/timewindow-config-dialog.component.ts
@@ -14,9 +14,8 @@
/// limitations under the License.
///
-import { Component, Inject, OnDestroy, OnInit } from '@angular/core';
+import { ChangeDetectorRef, Component, Inject, OnDestroy, OnInit, Renderer2, ViewContainerRef } from '@angular/core';
import {
- aggregationTranslations,
AggregationType,
DAY,
HistoryWindowType,
@@ -38,6 +37,11 @@ import { TranslateService } from '@ngx-translate/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
+import { TimezoneSelectionResult } from '@shared/components/time/timezone-panel.component';
+import { TbPopoverService } from '@shared/components/popover.service';
+import {
+ AggregationOptionsConfigPanelComponent
+} from '@shared/components/aggregation/aggregation-options-config-panel.component';
export interface TimewindowConfigDialogData {
quickIntervalOnly: boolean;
@@ -112,7 +116,11 @@ export class TimewindowConfigDialogComponent extends PageComponent implements On
protected store: Store,
public fb: FormBuilder,
private timeService: TimeService,
- private translate: TranslateService) {
+ private translate: TranslateService,
+ private popoverService: TbPopoverService,
+ private renderer: Renderer2,
+ private cd: ChangeDetectorRef,
+ public viewContainerRef: ViewContainerRef) {
super(store);
this.quickIntervalOnly = data.quickIntervalOnly;
this.aggregation = data.aggregation;
@@ -388,4 +396,30 @@ export class TimewindowConfigDialogComponent extends PageComponent implements On
}
}
+ openAggregationOptionsConfig($event: Event) {
+ if ($event) {
+ $event.stopPropagation();
+ }
+ const trigger = ($event.target || $event.srcElement || $event.currentTarget) as Element;
+ if (this.popoverService.hasPopover(trigger)) {
+ this.popoverService.hidePopover(trigger);
+ } else {
+ const aggregationConfigPopover = this.popoverService.displayPopover(trigger, this.renderer,
+ this.viewContainerRef, AggregationOptionsConfigPanelComponent, ['bottomRight', 'leftBottom'], true, null,
+ {
+ allowedAggregationTypes: null,
+ onClose: (result: TimezoneSelectionResult | null) => {
+ aggregationConfigPopover.hide();
+ if (result) {
+ console.log(result);
+ }
+ }
+ },
+ {},
+ {}, {}, false);
+ aggregationConfigPopover.tbComponentRef.instance.popoverComponent = aggregationConfigPopover;
+ }
+ this.cd.detectChanges();
+ }
+
}
diff --git a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts
index d29bc63f53..2037a3578b 100644
--- a/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts
+++ b/ui-ngx/src/app/shared/components/time/timewindow-panel.component.ts
@@ -16,7 +16,6 @@
import { Component, Inject, InjectionToken, OnDestroy, OnInit, ViewContainerRef } from '@angular/core';
import {
- aggregationTranslations,
AggregationType,
DAY,
HistoryWindowType,
diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts
index 23dc3e5a8f..2da898bd44 100644
--- a/ui-ngx/src/app/shared/shared.module.ts
+++ b/ui-ngx/src/app/shared/shared.module.ts
@@ -231,6 +231,7 @@ import { CountryData } from '@shared/models/country.models';
import { SvgXmlComponent } from '@shared/components/svg-xml.component';
import { DatapointsLimitComponent } from '@shared/components/time/datapoints-limit.component';
import { AggregationTypeSelectComponent } from '@shared/components/aggregation/aggregation-type-select.component';
+import { AggregationOptionsConfigPanelComponent } from '@shared/components/aggregation/aggregation-options-config-panel.component';
export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) {
return markedOptionsService;
@@ -322,6 +323,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
QuickTimeIntervalComponent,
DatapointsLimitComponent,
AggregationTypeSelectComponent,
+ AggregationOptionsConfigPanelComponent,
DashboardSelectComponent,
DashboardSelectPanelComponent,
DatetimePeriodComponent,
@@ -539,6 +541,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
QuickTimeIntervalComponent,
DatapointsLimitComponent,
AggregationTypeSelectComponent,
+ AggregationOptionsConfigPanelComponent,
DashboardSelectComponent,
DatetimePeriodComponent,
DatetimeComponent,