Timewindow: aggregation type select component introduced
This commit is contained in:
parent
b09266a54c
commit
6991acd42c
@ -333,11 +333,12 @@ import * as AssetProfileComponent from '@home/components/profile/asset-profile.c
|
||||
import * as AssetProfileDialogComponent from '@home/components/profile/asset-profile-dialog.component';
|
||||
import * as AssetProfileAutocompleteComponent from '@home/components/profile/asset-profile-autocomplete.component';
|
||||
import * as RuleChainSelectComponent from '@shared/components/rule-chain/rule-chain-select.component';
|
||||
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 { IModulesMap } from '@modules/common/modules-map.models';
|
||||
import { TimezoneComponent } from '@shared/components/time/timezone.component';
|
||||
import { TimezonePanelComponent } from '@shared/components/time/timezone-panel.component';
|
||||
import { DatapointsLimitComponent } from '@shared/components/time/datapoints-limit.component';
|
||||
|
||||
class ModulesMap implements IModulesMap {
|
||||
|
||||
@ -470,6 +471,7 @@ class ModulesMap implements IModulesMap {
|
||||
'@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/value-input.component': ValueInputComponent,
|
||||
'@shared/components/dashboard-autocomplete.component': DashboardAutocompleteComponent,
|
||||
'@shared/components/entity/entity-subtype-autocomplete.component': EntitySubTypeAutocompleteComponent,
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
<!--
|
||||
|
||||
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.
|
||||
|
||||
-->
|
||||
<mat-form-field [formGroup]="aggregationTypeFormGroup" [subscriptSizing]="subscriptSizing" [appearance]="appearance">
|
||||
<mat-label *ngIf="displayLabel">{{ label }}</mat-label>
|
||||
<mat-select [required]="required" formControlName="aggregationType">
|
||||
<mat-option *ngFor="let type of aggregationTypes" [value]="type">
|
||||
{{ displayAggregationTypeFn(type) }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
:host {
|
||||
.mat-mdc-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
:host ::ng-deep {
|
||||
.mat-mdc-form-field-infix {
|
||||
width: 100%;
|
||||
}
|
||||
.mat-mdc-select-value {
|
||||
min-width: 100px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,155 @@
|
||||
///
|
||||
/// 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, forwardRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
|
||||
import { ControlValueAccessor, FormBuilder, FormGroup, NG_VALUE_ACCESSOR } from '@angular/forms';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { coerceBoolean } from '@shared/decorators/coercion';
|
||||
import { MatFormFieldAppearance, SubscriptSizing } from '@angular/material/form-field';
|
||||
import { aggregationTranslations, AggregationType } from '@shared/models/time/time.models';
|
||||
|
||||
@Component({
|
||||
selector: 'tb-aggregation-type-select',
|
||||
templateUrl: './aggregation-type-select.component.html',
|
||||
styleUrls: ['./aggregation-type-select.component.scss'],
|
||||
providers: [{
|
||||
provide: NG_VALUE_ACCESSOR,
|
||||
useExisting: forwardRef(() => AggregationTypeSelectComponent),
|
||||
multi: true
|
||||
}]
|
||||
})
|
||||
export class AggregationTypeSelectComponent implements ControlValueAccessor, OnInit, OnChanges {
|
||||
|
||||
aggregationTypeFormGroup: FormGroup;
|
||||
|
||||
modelValue: AggregationType | null;
|
||||
|
||||
@Input()
|
||||
allowedAggregationTypes: Array<AggregationType>;
|
||||
|
||||
@Input()
|
||||
@coerceBoolean()
|
||||
required: boolean;
|
||||
|
||||
@Input()
|
||||
disabled: boolean;
|
||||
|
||||
@Input()
|
||||
@coerceBoolean()
|
||||
displayLabel = true;
|
||||
|
||||
@Input()
|
||||
labelText: string;
|
||||
|
||||
get label(): string {
|
||||
if (this.labelText && this.labelText.length) {
|
||||
return this.labelText;
|
||||
}
|
||||
return this.defaultLabel;
|
||||
}
|
||||
|
||||
@Input()
|
||||
subscriptSizing: SubscriptSizing = 'fixed';
|
||||
|
||||
@Input()
|
||||
appearance: MatFormFieldAppearance = 'fill';
|
||||
|
||||
aggregationTypes: Array<AggregationType>;
|
||||
|
||||
private defaultLabel = this.translate.instant('aggregation.aggregation');
|
||||
|
||||
private allAggregationTypes: Array<AggregationType> = Object.values(AggregationType);
|
||||
|
||||
private propagateChange = (v: any) => { };
|
||||
|
||||
constructor(private translate: TranslateService,
|
||||
private fb: FormBuilder) {
|
||||
this.aggregationTypeFormGroup = this.fb.group({
|
||||
aggregationType: [null]
|
||||
});
|
||||
}
|
||||
|
||||
registerOnChange(fn: any): void {
|
||||
this.propagateChange = fn;
|
||||
}
|
||||
|
||||
registerOnTouched(fn: any): void {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.aggregationTypes = this.allowedAggregationTypes?.length ? this.allowedAggregationTypes : this.allAggregationTypes;
|
||||
this.aggregationTypeFormGroup.get('aggregationType').valueChanges.subscribe(
|
||||
(value) => {
|
||||
let modelValue;
|
||||
if (!value || value === '') {
|
||||
modelValue = null;
|
||||
} else {
|
||||
modelValue = value;
|
||||
}
|
||||
this.updateView(modelValue);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
for (const propName of Object.keys(changes)) {
|
||||
const change = changes[propName];
|
||||
if (!change.firstChange && change.currentValue !== change.previousValue) {
|
||||
if (propName === 'allowedAggregationTypes') {
|
||||
this.aggregationTypes = this.allowedAggregationTypes?.length ? this.allowedAggregationTypes : this.allAggregationTypes;
|
||||
const currentAggregationType: AggregationType = this.aggregationTypeFormGroup.get('aggregationType').value;
|
||||
if (currentAggregationType && !this.aggregationTypes.includes(currentAggregationType)) {
|
||||
this.aggregationTypeFormGroup.get('aggregationType').patchValue(null, {emitEvent: true});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setDisabledState(isDisabled: boolean): void {
|
||||
this.disabled = isDisabled;
|
||||
if (this.disabled) {
|
||||
this.aggregationTypeFormGroup.disable();
|
||||
} else {
|
||||
this.aggregationTypeFormGroup.enable();
|
||||
}
|
||||
}
|
||||
|
||||
writeValue(value: AggregationType | null): void {
|
||||
if (value != null) {
|
||||
this.modelValue = value;
|
||||
this.aggregationTypeFormGroup.get('aggregationType').patchValue(value, {emitEvent: true});
|
||||
} else {
|
||||
this.modelValue = null;
|
||||
this.aggregationTypeFormGroup.get('aggregationType').patchValue(null, {emitEvent: true});
|
||||
}
|
||||
}
|
||||
|
||||
updateView(value: AggregationType | null) {
|
||||
if (this.modelValue !== value) {
|
||||
this.modelValue = value;
|
||||
this.propagateChange(this.modelValue);
|
||||
}
|
||||
}
|
||||
|
||||
displayAggregationTypeFn(aggregationType?: AggregationType | null): string | undefined {
|
||||
if (aggregationType) {
|
||||
return this.translate.instant(aggregationTranslations.get(aggregationType));
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,13 +167,9 @@
|
||||
</div>
|
||||
</mat-slide-toggle>
|
||||
<ng-container formGroupName="aggregation">
|
||||
<mat-form-field class="flex" subscriptSizing="dynamic" appearance="outline">
|
||||
<mat-select formControlName="type">
|
||||
<mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
|
||||
{{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<tb-aggregation-type-select class="flex" subscriptSizing="dynamic" appearance="outline" displayLabel="false"
|
||||
formControlName="type">
|
||||
</tb-aggregation-type-select>
|
||||
</ng-container>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@ -66,10 +66,6 @@ export class TimewindowConfigDialogComponent extends PageComponent implements On
|
||||
|
||||
aggregationTypes = AggregationType;
|
||||
|
||||
aggregations = Object.keys(AggregationType);
|
||||
|
||||
aggregationTypesTranslations = aggregationTranslations;
|
||||
|
||||
result: Timewindow;
|
||||
|
||||
timewindowTypeOptions: ToggleHeaderOption[] = [
|
||||
|
||||
@ -30,7 +30,8 @@
|
||||
tb-timeinterval,
|
||||
tb-quick-time-interval,
|
||||
tb-datetime-period,
|
||||
tb-datapoints-limit {
|
||||
tb-datapoints-limit,
|
||||
tb-aggregation-type-select {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,20 +125,16 @@
|
||||
<ng-container formGroupName="aggregation">
|
||||
<section class="tb-form-row column-xs space-between same-padding" *ngIf="isEdit || !timewindow.hideAggregation">
|
||||
<div class="fixed-title-width-180">{{ 'aggregation.aggregation' | translate }}</div>
|
||||
<mat-form-field class="flex" subscriptSizing="dynamic" appearance="outline">
|
||||
<mat-select formControlName="type">
|
||||
<mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
|
||||
{{ aggregationTypesTranslations.get(aggregationTypes[aggregation]) | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<tb-aggregation-type-select class="flex" subscriptSizing="dynamic" appearance="outline" displayLabel="false"
|
||||
formControlName="type">
|
||||
</tb-aggregation-type-select>
|
||||
</section>
|
||||
|
||||
<section class="tb-form-row column-xs space-between same-padding"
|
||||
*ngIf="timewindowForm.get('aggregation.type').value === aggregationTypes.NONE && (isEdit || !timewindow.hideAggInterval)">
|
||||
<div>{{ 'aggregation.limit' | translate }}</div>
|
||||
<tb-datapoints-limit formControlName="limit"
|
||||
[required]="timewindowForm.get('aggregation.type').value === aggregationTypes.NONE">
|
||||
[required]="timewindowForm.get('aggregation.type').value === aggregationTypes.MIN">
|
||||
</tb-datapoints-limit>
|
||||
</section>
|
||||
</ng-container>
|
||||
|
||||
@ -87,10 +87,6 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit, O
|
||||
|
||||
aggregationTypes = AggregationType;
|
||||
|
||||
aggregations = Object.keys(AggregationType);
|
||||
|
||||
aggregationTypesTranslations = aggregationTranslations;
|
||||
|
||||
result: Timewindow;
|
||||
|
||||
timewindowTypeOptions: ToggleHeaderOption[] = [{
|
||||
@ -517,4 +513,6 @@ export class TimewindowPanelComponent extends PageComponent implements OnInit, O
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected readonly AggregationType = AggregationType;
|
||||
}
|
||||
|
||||
@ -230,6 +230,7 @@ import { CountryAutocompleteComponent } from '@shared/components/country-autocom
|
||||
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';
|
||||
|
||||
export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) {
|
||||
return markedOptionsService;
|
||||
@ -320,6 +321,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
|
||||
TimezonePanelComponent,
|
||||
QuickTimeIntervalComponent,
|
||||
DatapointsLimitComponent,
|
||||
AggregationTypeSelectComponent,
|
||||
DashboardSelectComponent,
|
||||
DashboardSelectPanelComponent,
|
||||
DatetimePeriodComponent,
|
||||
@ -536,6 +538,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService)
|
||||
TimezonePanelComponent,
|
||||
QuickTimeIntervalComponent,
|
||||
DatapointsLimitComponent,
|
||||
AggregationTypeSelectComponent,
|
||||
DashboardSelectComponent,
|
||||
DatetimePeriodComponent,
|
||||
DatetimeComponent,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user