From 82ab52889bb6d1ee5fd600558f880020d1beaeed Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Fri, 12 Apr 2024 17:34:43 +0300 Subject: [PATCH] UI: Implement time series comparison widget settings. --- .../basic/basic-widget-config.module.ts | 8 +- .../chart/comparison-key-row.component.html | 37 +++++ .../chart/comparison-key-row.component.scss | 54 ++++++++ .../chart/comparison-key-row.component.ts | 131 ++++++++++++++++++ .../comparison-keys-table.component.html | 38 +++++ .../comparison-keys-table.component.scss | 53 +++++++ .../chart/comparison-keys-table.component.ts | 110 +++++++++++++++ ...e-series-chart-basic-config.component.html | 87 +++++++++--- ...ime-series-chart-basic-config.component.ts | 39 +++++- .../common/data-keys-panel.component.html | 6 +- .../basic/common/data-keys-panel.component.ts | 4 + .../widget/dynamic-widget.component.ts | 2 + .../lib/chart/time-series-chart.models.ts | 7 +- .../widget/lib/chart/time-series-chart.ts | 8 +- ...e-series-chart-key-settings.component.html | 29 ++++ ...ime-series-chart-key-settings.component.ts | 19 ++- ...eries-chart-widget-settings.component.html | 40 ++++++ ...-series-chart-widget-settings.component.ts | 20 ++- ...-chart-axis-settings-button.component.html | 28 ++++ ...es-chart-axis-settings-button.component.ts | 108 +++++++++++++++ ...-chart-axis-settings-panel.component.html} | 16 +-- ...-chart-axis-settings-panel.component.scss} | 8 +- ...es-chart-axis-settings-panel.component.ts} | 37 +++-- .../time-series-chart-y-axis-row.component.ts | 14 +- .../common/data-key-input.component.html | 4 +- .../common/data-key-input.component.scss | 7 + .../common/data-key-input.component.ts | 4 + .../common/widget-settings-common.module.ts | 13 +- .../home/models/widget-component.models.ts | 2 + .../assets/locale/locale.constant-en_US.json | 10 ++ ui-ngx/src/form.scss | 12 ++ 31 files changed, 890 insertions(+), 65 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.scss create mode 100644 ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.ts create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.html create mode 100644 ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.ts rename ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/{time-series-chart-y-axis-settings-panel.component.html => time-series-chart-axis-settings-panel.component.html} (69%) rename ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/{time-series-chart-y-axis-settings-panel.component.scss => time-series-chart-axis-settings-panel.component.scss} (89%) rename ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/{time-series-chart-y-axis-settings-panel.component.ts => time-series-chart-axis-settings-panel.component.ts} (56%) diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts index 2ff5142b9c..79ec4b03c7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts @@ -110,6 +110,10 @@ import { import { TimeSeriesChartBasicConfigComponent } from '@home/components/widget/config/basic/chart/time-series-chart-basic-config.component'; +import { ComparisonKeyRowComponent } from '@home/components/widget/config/basic/chart/comparison-key-row.component'; +import { + ComparisonKeysTableComponent +} from '@home/components/widget/config/basic/chart/comparison-keys-table.component'; @NgModule({ declarations: [ @@ -145,7 +149,9 @@ import { PowerButtonBasicConfigComponent, SliderBasicConfigComponent, ToggleButtonBasicConfigComponent, - TimeSeriesChartBasicConfigComponent + TimeSeriesChartBasicConfigComponent, + ComparisonKeyRowComponent, + ComparisonKeysTableComponent ], imports: [ CommonModule, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.html new file mode 100644 index 0000000000..79b9ecad15 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.html @@ -0,0 +1,37 @@ + +
+ + + +
+ + + +
+
+ + +
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.scss new file mode 100644 index 0000000000..a71d07371e --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.scss @@ -0,0 +1,54 @@ +/** + * 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 '../../../../../../../../scss/constants'; + +.tb-comparison-key-row { + .tb-show-field { + width: 40px; + min-width: 40px; + } + + .tb-data-key-input { + flex: 1; + @media #{$mat-gt-xs} { + min-width: 100px; + flex: 1 1 40%; + } + } + + .tb-label-field, .tb-color-field { + display: flex; + flex-direction: row; + place-content: center; + align-items: center; + .tb-inline-field { + flex: 1; + } + } + + .tb-label-field { + flex: 1; + @media #{$mat-gt-xs} { + min-width: 150px; + flex: 1 1 60%; + } + } + + .tb-color-field { + width: 40px; + min-width: 40px; + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.ts new file mode 100644 index 0000000000..8836a31f8b --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-key-row.component.ts @@ -0,0 +1,131 @@ +/// +/// 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 { ChangeDetectorRef, Component, forwardRef, Input, OnInit, ViewEncapsulation } from '@angular/core'; +import { + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormControl, + UntypedFormGroup +} from '@angular/forms'; +import { + DataKey, + DataKeyComparisonSettings, + DataKeySettingsWithComparison, + DatasourceType +} from '@shared/models/widget.models'; +import { deepClone } from '@core/utils'; + +@Component({ + selector: 'tb-comparison-key-row', + templateUrl: './comparison-key-row.component.html', + styleUrls: ['./comparison-key-row.component.scss', '../../data-keys.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => ComparisonKeyRowComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class ComparisonKeyRowComponent implements ControlValueAccessor, OnInit { + + @Input() + disabled: boolean; + + @Input() + datasourceType: DatasourceType; + + keyFormControl: UntypedFormControl; + + keyRowFormGroup: UntypedFormGroup; + + modelValue: DataKey; + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder, + private cd: ChangeDetectorRef) { + } + + ngOnInit() { + this.keyFormControl = this.fb.control(null, []); + this.keyRowFormGroup = this.fb.group({ + showValuesForComparison: [null, []], + comparisonValuesLabel: [null, []], + color: [null, []] + }); + this.keyRowFormGroup.valueChanges.subscribe( + () => this.updateModel() + ); + this.keyRowFormGroup.get('showValuesForComparison').valueChanges.subscribe(() => this.updateValidators()); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (isDisabled) { + this.keyFormControl.disable({emitEvent: false}); + this.keyRowFormGroup.disable({emitEvent: false}); + } else { + this.keyFormControl.enable({emitEvent: false}); + this.keyRowFormGroup.enable({emitEvent: false}); + this.updateValidators(); + } + } + + writeValue(value: DataKey): void { + this.modelValue = value; + const comparisonSettings = (value?.settings as DataKeySettingsWithComparison)?.comparisonSettings; + this.keyRowFormGroup.patchValue( + comparisonSettings, {emitEvent: false} + ); + this.keyFormControl.patchValue(deepClone(this.modelValue), {emitEvent: false}); + this.updateValidators(); + this.cd.markForCheck(); + } + + private updateValidators() { + const showValuesForComparison: boolean = this.keyRowFormGroup.get('showValuesForComparison').value; + if (showValuesForComparison) { + this.keyFormControl.enable({emitEvent: false}); + this.keyRowFormGroup.get('comparisonValuesLabel').enable({emitEvent: false}); + this.keyRowFormGroup.get('color').enable({emitEvent: false}); + } else { + this.keyFormControl.disable({emitEvent: false}); + this.keyRowFormGroup.get('comparisonValuesLabel').disable({emitEvent: false}); + this.keyRowFormGroup.get('color').disable({emitEvent: false}); + } + } + + private updateModel() { + const comparisonSettings: DataKeyComparisonSettings = this.keyRowFormGroup.value; + if (!this.modelValue.settings) { + this.modelValue.settings = {}; + } + this.modelValue.settings.comparisonSettings = comparisonSettings; + this.propagateChange(this.modelValue); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.html new file mode 100644 index 0000000000..a202a81cf6 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.html @@ -0,0 +1,38 @@ + +
+
+
widgets.time-series-chart.comparison.show
+
datakey.key
+
datakey.label
+
datakey.color
+
+
+
+ + +
+
+
+ + {{ 'widgets.chart.no-series' | translate }} + diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.scss new file mode 100644 index 0000000000..1d9689a333 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.scss @@ -0,0 +1,53 @@ +/** + * 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 '../../../../../../../../scss/constants'; + +.tb-comparison-keys-table { + .tb-form-table-header-cell { + + &.tb-show-header { + width: 40px; + min-width: 40px; + } + + &.tb-key-header { + flex: 1; + @media #{$mat-gt-xs} { + min-width: 100px; + flex: 1 1 40%; + } + } + + &.tb-label-header { + flex: 1; + @media #{$mat-gt-xs} { + min-width: 150px; + flex: 1 1 60%; + } + } + + &.tb-color-header { + width: 40px; + min-width: 40px; + } + } + + .tb-form-table-body { + tb-comparison-key-row { + overflow: hidden; + } + } +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.ts new file mode 100644 index 0000000000..b8241531b3 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/comparison-keys-table.component.ts @@ -0,0 +1,110 @@ +/// +/// 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, OnInit, ViewEncapsulation } from '@angular/core'; +import { + AbstractControl, + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormArray, + UntypedFormBuilder, + UntypedFormGroup +} from '@angular/forms'; +import { DataKey, DatasourceType } from '@shared/models/widget.models'; + +@Component({ + selector: 'tb-comparison-keys-table', + templateUrl: './comparison-keys-table.component.html', + styleUrls: ['./comparison-keys-table.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => ComparisonKeysTableComponent), + multi: true + } + ], + encapsulation: ViewEncapsulation.None +}) +export class ComparisonKeysTableComponent implements ControlValueAccessor, OnInit { + + @Input() + disabled: boolean; + + @Input() + datasourceType: DatasourceType; + + keysListFormGroup: UntypedFormGroup; + + get noKeys(): boolean { + const keys: DataKey[] = this.keysListFormGroup.get('keys').value; + return keys.length === 0; + } + + private propagateChange = (_val: any) => {}; + + constructor(private fb: UntypedFormBuilder) { + } + + ngOnInit() { + this.keysListFormGroup = this.fb.group({ + keys: [this.fb.array([]), []] + }); + this.keysListFormGroup.valueChanges.subscribe( + () => { + const keys: DataKey[] = this.keysListFormGroup.get('keys').value; + this.propagateChange(keys); + } + ); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + if (isDisabled) { + this.keysListFormGroup.disable({emitEvent: false}); + } else { + this.keysListFormGroup.enable({emitEvent: false}); + } + } + + writeValue(value: DataKey[] | undefined): void { + this.keysListFormGroup.setControl('keys', this.prepareKeysFormArray(value), {emitEvent: false}); + } + + keysFormArray(): UntypedFormArray { + return this.keysListFormGroup.get('keys') as UntypedFormArray; + } + + trackByKey(_index: number, keyControl: AbstractControl): any { + return keyControl; + } + + private prepareKeysFormArray(keys: DataKey[] | undefined): UntypedFormArray { + const keysControls: Array = []; + if (keys) { + keys.forEach((key) => { + keysControls.push(this.fb.control(key, [])); + }); + } + return this.fb.array(keysControls); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html index 80e13a96a2..bf88f77b2f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.html @@ -25,22 +25,77 @@ forceSingleDatasource formControlName="datasources"> - - +
+
+
{{ 'widgets.chart.series' | translate }}
+ + {{ 'widgets.chart.series' | translate }} + {{ 'widgets.time-series-chart.comparison.comparison' | translate }} + +
+ + +
+ + {{ 'widgets.time-series-chart.comparison.comparison' | translate }} + +
+ + + + {{ 'widgets.chart.time-for-comparison-previous-interval' | translate }} + + + {{ 'widgets.chart.time-for-comparison-days' | translate }} + + + {{ 'widgets.chart.time-for-comparison-weeks' | translate }} + + + {{ 'widgets.chart.time-for-comparison-months' | translate }} + + + {{ 'widgets.chart.time-for-comparison-years' | translate }} + + + {{ 'widgets.chart.time-for-comparison-custom-interval' | translate }} + + + + + + + + +
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts index 508709a3f9..789f3e9c33 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/time-series-chart-basic-config.component.ts @@ -23,6 +23,7 @@ import { WidgetConfigComponentData } from '@home/models/widget-component.models' import { DataKey, Datasource, + DatasourceType, legendPositions, legendPositionTranslationMap, WidgetConfig, @@ -89,6 +90,8 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon chartType: TimeSeriesChartType = TimeSeriesChartType.default; + seriesMode = 'series'; + constructor(protected store: Store, protected widgetConfigComponent: WidgetConfigComponent, private $injector: Injector, @@ -105,6 +108,11 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon } } + seriesModeChange(seriesMode: string) { + this.seriesMode = seriesMode; + this.updateSeriesState(); + } + protected configForm(): UntypedFormGroup { return this.timeSeriesChartWidgetConfigForm; } @@ -135,6 +143,7 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon comparisonEnabled: [settings.comparisonEnabled, []], timeForComparison: [settings.timeForComparison, []], comparisonCustomIntervalValue: [settings.comparisonCustomIntervalValue, [Validators.min(0)]], + comparisonXAxis: [settings.comparisonXAxis, []], thresholds: [settings.thresholds, []], @@ -187,6 +196,7 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon if (this.chartType === TimeSeriesChartType.state) { this.timeSeriesChartWidgetConfigForm.addControl('states', this.fb.control(settings.states, [])); } + this.timeSeriesChartWidgetConfigForm.get('comparisonEnabled').valueChanges.subscribe(() => this.updateSeriesState()); } protected prepareOutputConfig(config: any): WidgetConfigComponentData { @@ -209,6 +219,7 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon this.widgetConfig.config.settings.comparisonEnabled = config.comparisonEnabled; this.widgetConfig.config.settings.timeForComparison = config.timeForComparison; this.widgetConfig.config.settings.comparisonCustomIntervalValue = config.comparisonCustomIntervalValue; + this.widgetConfig.config.settings.comparisonXAxis = config.comparisonXAxis; this.widgetConfig.config.settings.thresholds = config.thresholds; @@ -254,16 +265,27 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon } protected validatorTriggers(): string[] { - return ['showTitle', 'showIcon', 'showLegend', 'showTooltip', 'tooltipShowDate']; + return ['comparisonEnabled', 'showTitle', 'showIcon', 'showLegend', 'showTooltip', 'tooltipShowDate']; } protected updateValidators(emitEvent: boolean, trigger?: string) { + const comparisonEnabled: boolean = this.timeSeriesChartWidgetConfigForm.get('comparisonEnabled').value; const showTitle: boolean = this.timeSeriesChartWidgetConfigForm.get('showTitle').value; const showIcon: boolean = this.timeSeriesChartWidgetConfigForm.get('showIcon').value; const showLegend: boolean = this.timeSeriesChartWidgetConfigForm.get('showLegend').value; const showTooltip: boolean = this.timeSeriesChartWidgetConfigForm.get('showTooltip').value; const tooltipShowDate: boolean = this.timeSeriesChartWidgetConfigForm.get('tooltipShowDate').value; + if (comparisonEnabled) { + this.timeSeriesChartWidgetConfigForm.get('timeForComparison').enable(); + this.timeSeriesChartWidgetConfigForm.get('comparisonCustomIntervalValue').enable(); + this.timeSeriesChartWidgetConfigForm.get('comparisonXAxis').enable(); + } else { + this.timeSeriesChartWidgetConfigForm.get('timeForComparison').disable(); + this.timeSeriesChartWidgetConfigForm.get('comparisonCustomIntervalValue').disable(); + this.timeSeriesChartWidgetConfigForm.get('comparisonXAxis').disable(); + } + if (showTitle) { this.timeSeriesChartWidgetConfigForm.get('title').enable(); this.timeSeriesChartWidgetConfigForm.get('titleFont').enable(); @@ -345,6 +367,19 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon } } + private updateSeriesState() { + if (this.seriesMode === 'series') { + this.timeSeriesChartWidgetConfigForm.get('series').enable({emitEvent: false}); + } else { + const comparisonEnabled = this.timeSeriesChartWidgetConfigForm.get('comparisonEnabled').value; + if (comparisonEnabled) { + this.timeSeriesChartWidgetConfigForm.get('series').enable({emitEvent: false}); + } else { + this.timeSeriesChartWidgetConfigForm.get('series').disable({emitEvent: false}); + } + } + } + private removeYaxisId(series: DataKey[], yAxisId: TimeSeriesChartYAxisId): boolean { let changed = false; if (series) { @@ -381,4 +416,6 @@ export class TimeSeriesChartBasicConfigComponent extends BasicWidgetConfigCompon processor.update(Date.now()); return processor.formatted; } + + protected readonly DatasourceType = DatasourceType; } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html index f140bd7445..59a3bcb3cb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.html @@ -15,8 +15,10 @@ limitations under the License. --> -
-
{{ panelTitle }}
+
+
{{ panelTitle }}
datakey.source
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts index 86367771de..67ed19b2d2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-keys-panel.component.ts @@ -96,6 +96,10 @@ export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnC @Input() deviceId: string; + @Input() + @coerceBoolean() + hidePanel = false; + @Input() @coerceBoolean() hideDataKeyColor = false; diff --git a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts index 6cef868e66..d047abdec5 100644 --- a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts @@ -49,6 +49,7 @@ import { TbInject } from '@shared/decorators/tb-inject'; import { MillisecondsToTimeStringPipe } from '@shared/pipe/milliseconds-to-time-string.pipe'; import { UserSettingsService } from '@core/http/user-settings.service'; import { ImagePipe } from '@shared/pipe/image.pipe'; +import { UtilsService } from '@core/services/utils.service'; @Directive() // eslint-disable-next-line @angular-eslint/directive-class-suffix @@ -86,6 +87,7 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid this.ctx.customDialog = $injector.get(CustomDialogService); this.ctx.resourceService = $injector.get(ResourceService); this.ctx.userSettingsService = $injector.get(UserSettingsService); + this.ctx.utilsService = $injector.get(UtilsService); this.ctx.telemetryWsService = $injector.get(TelemetryWebsocketService); this.ctx.date = $injector.get(DatePipe); this.ctx.imagePipe = $injector.get(ImagePipe); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts index db3831f6a3..6131aa0f1d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.models.ts @@ -71,6 +71,7 @@ import { DatePipe } from '@angular/common'; import { BuiltinTextPosition } from 'zrender/src/core/types'; import { CartesianAxisOption } from 'echarts/types/src/coord/cartesian/AxisModel'; import { WidgetTimewindow } from '@shared/models/time/time.models'; +import { UtilsService } from '@core/services/utils.service'; export enum TimeSeriesChartType { default = 'default', @@ -932,6 +933,7 @@ export interface TimeSeriesChartXAxis extends TimeSeriesChartAxis { export const createTimeSeriesYAxis = (units: string, decimals: number, settings: TimeSeriesChartYAxisSettings, + utils: UtilsService, darkMode: boolean): TimeSeriesChartYAxis => { const yAxisTickLabelStyle = createChartTextStyle(settings.tickLabelFont, settings.tickLabelColor, darkMode, 'axis.tickLabel'); @@ -986,7 +988,7 @@ export const createTimeSeriesYAxis = (units: string, splitNumber, interval, ticksGenerator, - name: settings.label, + name: utils.customTranslation(settings.label, settings.label), nameLocation: 'middle', nameRotate: settings.position === AxisPosition.left ? 90 : -90, nameTextStyle: { @@ -1044,6 +1046,7 @@ export const createTimeSeriesXAxis = (id: string, settings: TimeSeriesChartXAxisSettings, min: number, max: number, datePipe: DatePipe, + utils: UtilsService, darkMode: boolean): TimeSeriesChartXAxis => { const xAxisTickLabelStyle = createChartTextStyle(settings.tickLabelFont, settings.tickLabelColor, darkMode, 'axis.tickLabel'); @@ -1060,7 +1063,7 @@ export const createTimeSeriesXAxis = (id: string, scale: true, position: settings.position, id, - name: settings.label, + name: utils.customTranslation(settings.label, settings.label), nameLocation: 'middle', nameTextStyle: { color: xAxisNameStyle.color, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts index 89aa599afb..6fd6da0199 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/chart/time-series-chart.ts @@ -170,7 +170,7 @@ export class TbTimeSeriesChart { this.comparisonEnabled = !!this.ctx.defaultSubscription.comparisonEnabled; this.stackMode = !this.comparisonEnabled && this.settings.stack; if (this.settings.states && this.settings.states.length) { - this.stateValueConverter = new TimeSeriesChartStateValueConverter(this.ctx.dashboard.utils, this.settings.states); + this.stateValueConverter = new TimeSeriesChartStateValueConverter(this.ctx.utilsService, this.settings.states); this.tooltipValueFormatFunction = this.stateValueConverter.tooltipFormatter; } const $dashboardPageElement = this.ctx.$containerParent.parents('.tb-dashboard-page'); @@ -503,12 +503,12 @@ export class TbTimeSeriesChart { private setupXAxes(): void { const mainXAxis = createTimeSeriesXAxis('main', this.settings.xAxis, this.ctx.defaultSubscription.timeWindow.minTime, - this.ctx.defaultSubscription.timeWindow.maxTime, this.ctx.date, this.darkMode); + this.ctx.defaultSubscription.timeWindow.maxTime, this.ctx.date, this.ctx.utilsService, this.darkMode); this.xAxisList.push(mainXAxis); if (this.comparisonEnabled) { const comparisonXAxis = createTimeSeriesXAxis('comparison', this.settings.comparisonXAxis, this.ctx.defaultSubscription.comparisonTimeWindow.minTime, this.ctx.defaultSubscription.comparisonTimeWindow.maxTime, - this.ctx.date, this.darkMode); + this.ctx.date, this.ctx.utilsService, this.darkMode); this.xAxisList.push(comparisonXAxis); } } @@ -526,7 +526,7 @@ export class TbTimeSeriesChart { axisSettings.ticksGenerator = this.stateValueConverter.ticksGenerator; axisSettings.ticksFormatter = this.stateValueConverter.ticksFormatter; } - const yAxis = createTimeSeriesYAxis(units, decimals, axisSettings, this.darkMode); + const yAxis = createTimeSeriesYAxis(units, decimals, axisSettings, this.ctx.utilsService, this.darkMode); this.yAxisList.push(yAxis); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html index 6d015e04fa..a265a1b431 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.html @@ -66,6 +66,35 @@ helpId="widget/lib/flot/tooltip_value_format_fn">
+
+
widgets.time-series-chart.comparison.settings
+ + + + + {{ 'widgets.time-series-chart.comparison.show-values-for-comparison' | translate }} + + + + +
+
widgets.time-series-chart.comparison.comparison-values-label
+ + + +
+
+
{{ 'widgets.time-series-chart.comparison.comparison-data-color' | translate }}
+ + +
+
+
+
{{ timeSeriesChartTypeTranslations.get(chartType) | translate }}
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.ts index b2495f5dda..229607d7f3 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-key-settings.component.ts @@ -54,6 +54,8 @@ export class TimeSeriesChartKeySettingsComponent extends WidgetSettingsComponent yAxisIds: TimeSeriesChartYAxisId[]; + comparisonEnabled: boolean; + functionScopeVariables = this.widgetService.getWidgetScopeVariables(); constructor(protected store: Store, @@ -73,6 +75,7 @@ export class TimeSeriesChartKeySettingsComponent extends WidgetSettingsComponent } const widgetSettings = (widgetConfig.config?.settings || {}) as TimeSeriesChartWidgetSettings; this.yAxisIds = widgetSettings.yAxes ? Object.keys(widgetSettings.yAxes) : ['default']; + this.comparisonEnabled = !!widgetSettings.comparisonEnabled; } protected defaultSettings(): WidgetSettings { @@ -103,12 +106,14 @@ export class TimeSeriesChartKeySettingsComponent extends WidgetSettingsComponent } protected validatorTriggers(): string[] { - return ['showInLegend', 'type']; + return ['showInLegend', 'type', 'comparisonSettings.showValuesForComparison']; } protected updateValidators(_emitEvent: boolean) { const showInLegend: boolean = this.timeSeriesChartKeySettingsForm.get('showInLegend').value; const type: TimeSeriesChartSeriesType = this.timeSeriesChartKeySettingsForm.get('type').value; + const showValuesForComparison: boolean = + this.timeSeriesChartKeySettingsForm.get('comparisonSettings').get('showValuesForComparison').value; if (showInLegend) { this.timeSeriesChartKeySettingsForm.get('dataHiddenByDefault').enable(); } else { @@ -122,5 +127,17 @@ export class TimeSeriesChartKeySettingsComponent extends WidgetSettingsComponent this.timeSeriesChartKeySettingsForm.get('lineSettings').disable(); this.timeSeriesChartKeySettingsForm.get('barSettings').enable(); } + if (this.comparisonEnabled) { + this.timeSeriesChartKeySettingsForm.get('comparisonSettings').enable({emitEvent: false}); + if (showValuesForComparison) { + this.timeSeriesChartKeySettingsForm.get('comparisonSettings').get('comparisonValuesLabel').enable(); + this.timeSeriesChartKeySettingsForm.get('comparisonSettings').get('color').enable(); + } else { + this.timeSeriesChartKeySettingsForm.get('comparisonSettings').get('comparisonValuesLabel').disable(); + this.timeSeriesChartKeySettingsForm.get('comparisonSettings').get('color').disable(); + } + } else { + this.timeSeriesChartKeySettingsForm.get('comparisonSettings').disable({emitEvent: false}); + } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html index d98f9ee319..5afcd9c860 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.html @@ -16,6 +16,46 @@ --> +
+
+ + {{ 'widgets.time-series-chart.comparison.comparison' | translate }} + +
+ + + + {{ 'widgets.chart.time-for-comparison-previous-interval' | translate }} + + + {{ 'widgets.chart.time-for-comparison-days' | translate }} + + + {{ 'widgets.chart.time-for-comparison-weeks' | translate }} + + + {{ 'widgets.chart.time-for-comparison-months' | translate }} + + + {{ 'widgets.chart.time-for-comparison-years' | translate }} + + + {{ 'widgets.chart.time-for-comparison-custom-interval' | translate }} + + + + + + + + +
+
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts index 01ecca2944..6dff6e1496 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/time-series-chart-widget-settings.component.ts @@ -23,7 +23,7 @@ import { WidgetSettings, WidgetSettingsComponent } from '@shared/models/widget.models'; -import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { formatValue, isDefinedAndNotNull, mergeDeep } from '@core/utils'; @@ -114,6 +114,11 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon protected onSettingsSet(settings: WidgetSettings) { this.timeSeriesChartWidgetSettingsForm = this.fb.group({ + comparisonEnabled: [settings.comparisonEnabled, []], + timeForComparison: [settings.timeForComparison, []], + comparisonCustomIntervalValue: [settings.comparisonCustomIntervalValue, [Validators.min(0)]], + comparisonXAxis: [settings.comparisonXAxis, []], + yAxes: [settings.yAxes, []], thresholds: [settings.thresholds, []], @@ -154,14 +159,25 @@ export class TimeSeriesChartWidgetSettingsComponent extends WidgetSettingsCompon } protected validatorTriggers(): string[] { - return ['showLegend', 'showTooltip', 'tooltipShowDate']; + return ['comparisonEnabled', 'showLegend', 'showTooltip', 'tooltipShowDate']; } protected updateValidators(emitEvent: boolean) { + const comparisonEnabled: boolean = this.timeSeriesChartWidgetSettingsForm.get('comparisonEnabled').value; const showLegend: boolean = this.timeSeriesChartWidgetSettingsForm.get('showLegend').value; const showTooltip: boolean = this.timeSeriesChartWidgetSettingsForm.get('showTooltip').value; const tooltipShowDate: boolean = this.timeSeriesChartWidgetSettingsForm.get('tooltipShowDate').value; + if (comparisonEnabled) { + this.timeSeriesChartWidgetSettingsForm.get('timeForComparison').enable(); + this.timeSeriesChartWidgetSettingsForm.get('comparisonCustomIntervalValue').enable(); + this.timeSeriesChartWidgetSettingsForm.get('comparisonXAxis').enable(); + } else { + this.timeSeriesChartWidgetSettingsForm.get('timeForComparison').disable(); + this.timeSeriesChartWidgetSettingsForm.get('comparisonCustomIntervalValue').disable(); + this.timeSeriesChartWidgetSettingsForm.get('comparisonXAxis').disable(); + } + if (showLegend) { this.timeSeriesChartWidgetSettingsForm.get('legendLabelFont').enable(); this.timeSeriesChartWidgetSettingsForm.get('legendLabelColor').enable(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.html new file mode 100644 index 0000000000..cd7a26441a --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.html @@ -0,0 +1,28 @@ + + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.ts new file mode 100644 index 0000000000..7072d7051f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-button.component.ts @@ -0,0 +1,108 @@ +/// +/// 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, OnInit, Renderer2, ViewContainerRef } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { MatButton } from '@angular/material/button'; +import { TbPopoverService } from '@shared/components/popover.service'; +import { coerceBoolean } from '@shared/decorators/coercion'; +import { TimeSeriesChartAxisSettings } from '@home/components/widget/lib/chart/time-series-chart.models'; +import { + TimeSeriesChartAxisSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component'; + +@Component({ + selector: 'tb-time-series-chart-axis-settings-button', + templateUrl: './time-series-chart-axis-settings-button.component.html', + styleUrls: [], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => TimeSeriesChartAxisSettingsButtonComponent), + multi: true + } + ] +}) +export class TimeSeriesChartAxisSettingsButtonComponent implements OnInit, ControlValueAccessor { + + @Input() + disabled: boolean; + + @Input() + axisType: 'xAxis' | 'yAxis' = 'xAxis'; + + @Input() + panelTitle: string; + + @Input() + @coerceBoolean() + advanced = false; + + private modelValue: TimeSeriesChartAxisSettings; + + private propagateChange = null; + + constructor(private popoverService: TbPopoverService, + private renderer: Renderer2, + private viewContainerRef: ViewContainerRef) {} + + ngOnInit(): void { + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(_fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + } + + writeValue(value: TimeSeriesChartAxisSettings): void { + this.modelValue = value; + } + + openAxisSettingsPopup($event: Event, matButton: MatButton) { + if ($event) { + $event.stopPropagation(); + } + const trigger = matButton._elementRef.nativeElement; + if (this.popoverService.hasPopover(trigger)) { + this.popoverService.hidePopover(trigger); + } else { + const ctx: any = { + axisSettings: this.modelValue, + axisType: this.axisType, + panelTitle: this.panelTitle, + advanced: this.advanced + }; + const axisSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, + this.viewContainerRef, TimeSeriesChartAxisSettingsPanelComponent, ['leftOnly', 'leftTopOnly', 'leftBottomOnly'], true, null, + ctx, + {}, + {}, {}, true); + axisSettingsPanelPopover.tbComponentRef.instance.popover = axisSettingsPanelPopover; + axisSettingsPanelPopover.tbComponentRef.instance.axisSettingsApplied.subscribe((axisSettings) => { + axisSettingsPanelPopover.hide(); + this.modelValue = axisSettings; + this.propagateChange(this.modelValue); + }); + } + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.html similarity index 69% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.html rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.html index 759074b4be..dbc74d9ed1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.html @@ -15,17 +15,17 @@ limitations under the License. --> -
-
{{ 'widgets.time-series-chart.axis.y-axis-settings' | translate }}
-
+
+
{{ panelTitle }}
+
+ [axisType]="axisType">
-
+
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.scss similarity index 89% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.scss rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.scss index 095c38b7f7..853057c24e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.scss @@ -15,7 +15,7 @@ */ @import '../../../../../../../../../scss/constants'; -.tb-y-axis-settings-panel { +.tb-axis-settings-panel { width: 530px; display: flex; flex-direction: column; @@ -23,7 +23,7 @@ @media #{$mat-lt-md} { width: 90vw; } - .tb-y-axis-settings-panel-content { + .tb-axis-settings-panel-content { display: flex; flex-direction: column; gap: 16px; @@ -31,14 +31,14 @@ margin: -10px; padding: 10px; } - .tb-y-axis-settings-title { + .tb-axis-settings-title { font-size: 16px; font-weight: 500; line-height: 24px; letter-spacing: 0.25px; color: rgba(0, 0, 0, 0.87); } - .tb-y-axis-settings-panel-buttons { + .tb-axis-settings-panel-buttons { height: 40px; display: flex; flex-direction: row; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.ts similarity index 56% rename from ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.ts rename to ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.ts index 8046aafd29..ebfbcf84a1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component.ts @@ -17,40 +17,49 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; import { TbPopoverComponent } from '@shared/components/popover.component'; import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; -import { TimeSeriesChartYAxisSettings } from '@home/components/widget/lib/chart/time-series-chart.models'; +import { + TimeSeriesChartAxisSettings, + TimeSeriesChartYAxisSettings +} from '@home/components/widget/lib/chart/time-series-chart.models'; import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ - selector: 'tb-time-series-chart-y-axis-settings-panel', - templateUrl: './time-series-chart-y-axis-settings-panel.component.html', + selector: 'tb-time-series-chart-axis-settings-panel', + templateUrl: './time-series-chart-axis-settings-panel.component.html', providers: [], - styleUrls: ['./time-series-chart-y-axis-settings-panel.component.scss'], + styleUrls: ['./time-series-chart-axis-settings-panel.component.scss'], encapsulation: ViewEncapsulation.None }) -export class TimeSeriesChartYAxisSettingsPanelComponent implements OnInit { +export class TimeSeriesChartAxisSettingsPanelComponent implements OnInit { @Input() - yAxisSettings: TimeSeriesChartYAxisSettings; + axisType: 'xAxis' | 'yAxis' = 'xAxis'; + + @Input() + panelTitle: string; + + @Input() + axisSettings: TimeSeriesChartAxisSettings; @Input() @coerceBoolean() advanced = false; @Input() - popover: TbPopoverComponent; + popover: TbPopoverComponent; @Output() - yAxisSettingsApplied = new EventEmitter(); + axisSettingsApplied = new EventEmitter(); - yAxisSettingsFormGroup: UntypedFormGroup; + axisSettingsFormGroup: UntypedFormGroup; constructor(private fb: UntypedFormBuilder) { } ngOnInit(): void { - this.yAxisSettingsFormGroup = this.fb.group( + this.axisSettingsFormGroup = this.fb.group( { - yAxis: [this.yAxisSettings, []] + axis: [this.axisSettings, []] } ); } @@ -59,8 +68,8 @@ export class TimeSeriesChartYAxisSettingsPanelComponent implements OnInit { this.popover?.hide(); } - applyYAxisSettings() { - const yAxisSettings = this.yAxisSettingsFormGroup.get('yAxis').getRawValue(); - this.yAxisSettingsApplied.emit(yAxisSettings); + applyAxisSettings() { + const axisSettings = this.axisSettingsFormGroup.get('axis').getRawValue(); + this.axisSettingsApplied.emit(axisSettings); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts index a4824fd51e..3fcde90cef 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-row.component.ts @@ -36,9 +36,10 @@ import { MatButton } from '@angular/material/button'; import { TbPopoverService } from '@shared/components/popover.service'; import { coerceBoolean } from '@shared/decorators/coercion'; import { - TimeSeriesChartYAxisSettingsPanelComponent -} from '@home/components/widget/lib/settings/common/chart/time-series-chart-y-axis-settings-panel.component'; + TimeSeriesChartAxisSettingsPanelComponent +} from '@home/components/widget/lib/settings/common/chart/time-series-chart-axis-settings-panel.component'; import { deepClone } from '@core/utils'; +import { TranslateService } from '@ngx-translate/core'; @Component({ selector: 'tb-time-series-chart-y-axis-row', @@ -76,6 +77,7 @@ export class TimeSeriesChartYAxisRowComponent implements ControlValueAccessor, O private propagateChange = (_val: any) => {}; constructor(private fb: UntypedFormBuilder, + private translate: TranslateService, private popoverService: TbPopoverService, private renderer: Renderer2, private viewContainerRef: ViewContainerRef, @@ -143,16 +145,18 @@ export class TimeSeriesChartYAxisRowComponent implements ControlValueAccessor, O this.popoverService.hidePopover(trigger); } else { const ctx: any = { - yAxisSettings: deepClone(this.modelValue), + axisType: 'yAxis', + panelTitle: this.translate.instant('widgets.time-series-chart.axis.y-axis-settings'), + axisSettings: deepClone(this.modelValue), advanced: this.advanced }; const yAxisSettingsPanelPopover = this.popoverService.displayPopover(trigger, this.renderer, - this.viewContainerRef, TimeSeriesChartYAxisSettingsPanelComponent, ['leftOnly', 'leftTopOnly', 'leftBottomOnly'], true, null, + this.viewContainerRef, TimeSeriesChartAxisSettingsPanelComponent, ['leftOnly', 'leftTopOnly', 'leftBottomOnly'], true, null, ctx, {}, {}, {}, true); yAxisSettingsPanelPopover.tbComponentRef.instance.popover = yAxisSettingsPanelPopover; - yAxisSettingsPanelPopover.tbComponentRef.instance.yAxisSettingsApplied.subscribe((yAxisSettings) => { + yAxisSettingsPanelPopover.tbComponentRef.instance.axisSettingsApplied.subscribe((yAxisSettings) => { yAxisSettingsPanelPopover.hide(); this.modelValue = {...this.modelValue, ...yAxisSettings}; this.axisFormGroup.patchValue( diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/data-key-input.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/data-key-input.component.html index 94831b530f..d5cc9a183e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/data-key-input.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/data-key-input.component.html @@ -19,6 +19,7 @@ [class.tb-suffix-absolute]="!keysFormControl.value?.length">
@@ -49,7 +50,8 @@ (click)="editKey()" mat-icon-button class="tb-mat-24"> edit -