diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.html b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.html index 837c0abcad..c3d4caca14 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.html @@ -54,11 +54,13 @@ - - +
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.scss b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.scss index 9777decdb0..c31f1d5791 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.scss +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/edit-widget.component.scss @@ -14,9 +14,17 @@ * limitations under the License. */ :host { - .widget-preview-section { + .widget-preview-background { position: absolute; top: 72px; + left: 0; + right: 0; + bottom: 0; + background: #fff; + } + .widget-preview-section { + position: absolute; + top: 0; left: 16px; right: 16px; bottom: 16px; 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 f292198f1e..8b90de1ef0 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 @@ -33,6 +33,8 @@ import { DataKeyRowComponent } from '@home/components/widget/config/basic/common import { TimeseriesTableBasicConfigComponent } from '@home/components/widget/config/basic/cards/timeseries-table-basic-config.component'; +import { FlotBasicConfigComponent } from '@home/components/widget/config/basic/chart/flot-basic-config.component'; +import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module'; @NgModule({ declarations: [ @@ -40,12 +42,14 @@ import { SimpleCardBasicConfigComponent, EntitiesTableBasicConfigComponent, TimeseriesTableBasicConfigComponent, + FlotBasicConfigComponent, DataKeyRowComponent, DataKeysPanelComponent ], imports: [ CommonModule, SharedModule, + WidgetSettingsModule, WidgetConfigComponentsModule ], exports: [ @@ -53,6 +57,7 @@ import { SimpleCardBasicConfigComponent, EntitiesTableBasicConfigComponent, TimeseriesTableBasicConfigComponent, + FlotBasicConfigComponent, DataKeyRowComponent, DataKeysPanelComponent ] @@ -63,5 +68,6 @@ export class BasicWidgetConfigModule { export const basicWidgetConfigComponentsMap: {[key: string]: Type} = { 'tb-simple-card-basic-config': SimpleCardBasicConfigComponent, 'tb-entities-table-basic-config': EntitiesTableBasicConfigComponent, - 'tb-timeseries-table-basic-config': TimeseriesTableBasicConfigComponent + 'tb-timeseries-table-basic-config': TimeseriesTableBasicConfigComponent, + 'tb-flot-basic-config': FlotBasicConfigComponent }; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html index aca3394f8c..bc406895c7 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.html @@ -40,7 +40,7 @@
widget-config.appearance
- + {{ 'widget-config.card-title' | translate }} @@ -63,7 +63,7 @@
-
widgets.table.show-card-buttons
+
widget-config.show-card-buttons
{{ 'action.search' | translate }} {{ 'widgets.table.columns-to-display' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts index b0897f05bc..2061832918 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/entities-table-basic-config.component.ts @@ -29,6 +29,7 @@ import { import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { isUndefined } from '@core/utils'; +import { getTimewindowConfig } from '@home/components/widget/config/timewindow-config-panel.component'; @Component({ selector: 'tb-entities-table-basic-config', @@ -74,11 +75,7 @@ export class EntitiesTableBasicConfigComponent extends BasicWidgetConfigComponen protected onConfigSet(configData: WidgetConfigComponentData) { this.entitiesTableWidgetConfigForm = this.fb.group({ - timewindowConfig: [{ - useDashboardTimewindow: configData.config.useDashboardTimewindow, - displayTimewindow: configData.config.displayTimewindow, - timewindow: configData.config.timewindow - }, []], + timewindowConfig: [getTimewindowConfig(configData.config), []], datasources: [configData.config.datasources, []], columns: [this.getColumns(configData.config.datasources), []], showTitle: [configData.config.showTitle, []], diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html index 28cd0aaa6e..5c16b9f195 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html @@ -31,7 +31,7 @@
widget-config.appearance
-
widgets.simple-card.label
+
widgets.simple-card.label
@@ -57,7 +57,7 @@
widget-config.decimals-short
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts index b59170fb89..b0e03d66d0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts @@ -27,6 +27,7 @@ import { } from '@shared/models/widget.models'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { getTimewindowConfig } from '@home/components/widget/config/timewindow-config-panel.component'; @Component({ selector: 'tb-simple-card-basic-config', @@ -63,11 +64,7 @@ export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent { protected onConfigSet(configData: WidgetConfigComponentData) { this.simpleCardWidgetConfigForm = this.fb.group({ - timewindowConfig: [{ - useDashboardTimewindow: configData.config.useDashboardTimewindow, - displayTimewindow: configData.config.useDashboardTimewindow, - timewindow: configData.config.timewindow - }, []], + timewindowConfig: [getTimewindowConfig(configData.config), []], datasources: [configData.config.datasources, []], label: [this.getDataKeyLabel(configData.config.datasources), []], labelPosition: [configData.config.settings?.labelPosition, []], diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html index 158b734a4a..a0c3d64e25 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.html @@ -21,6 +21,7 @@
widget-config.appearance
- + {{ 'widget-config.card-title' | translate }} @@ -62,7 +63,7 @@
-
widgets.table.show-card-buttons
+
widget-config.show-card-buttons
{{ 'action.search' | translate }} {{ 'widgets.table.columns-to-display' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts index e650f9a344..ac1b12167c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/cards/timeseries-table-basic-config.component.ts @@ -20,15 +20,11 @@ import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; import { WidgetConfigComponentData } from '@home/models/widget-component.models'; -import { - DataKey, - Datasource, - datasourcesHasAggregation, - datasourcesHasOnlyComparisonAggregation, WidgetConfig -} from '@shared/models/widget.models'; +import { DataKey, Datasource, WidgetConfig } from '@shared/models/widget.models'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { deepClone, isUndefined } from '@core/utils'; +import { getTimewindowConfig } from '@home/components/widget/config/timewindow-config-panel.component'; @Component({ selector: 'tb-timeseries-table-basic-config', @@ -65,11 +61,7 @@ export class TimeseriesTableBasicConfigComponent extends BasicWidgetConfigCompon protected onConfigSet(configData: WidgetConfigComponentData) { this.timeseriesTableWidgetConfigForm = this.fb.group({ - timewindowConfig: [{ - useDashboardTimewindow: configData.config.useDashboardTimewindow, - displayTimewindow: configData.config.displayTimewindow, - timewindow: configData.config.timewindow - }, []], + timewindowConfig: [getTimewindowConfig(configData.config), []], datasources: [configData.config.datasources, []], columns: [this.getColumns(configData.config.datasources), []], showTitle: [configData.config.showTitle, []], @@ -92,11 +84,11 @@ export class TimeseriesTableBasicConfigComponent extends BasicWidgetConfigCompon this.setColumns(config.columns, this.widgetConfig.config.datasources); this.widgetConfig.config.actions = config.actions; this.widgetConfig.config.showTitle = config.showTitle; - this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; - this.widgetConfig.config.settings.entitiesTitle = config.title; + this.widgetConfig.config.title = config.title; this.widgetConfig.config.showTitleIcon = config.showTitleIcon; this.widgetConfig.config.titleIcon = config.titleIcon; this.widgetConfig.config.iconColor = config.iconColor; + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; this.setCardButtons(config.cardButtons, this.widgetConfig.config); this.widgetConfig.config.color = config.color; this.widgetConfig.config.backgroundColor = config.backgroundColor; diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html new file mode 100644 index 0000000000..0fff9342fd --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.html @@ -0,0 +1,113 @@ + + + + + + + + +
+
widget-config.card-appearance
+
+ + {{ 'widget-config.card-title' | translate }} + + + + +
+
+ + {{ 'widget-config.card-icon' | translate }} + +
+ + + + + +
+
+
+
widget-config.show-card-buttons
+ + {{ 'fullscreen.fullscreen' | translate }} + +
+
+
{{ 'widget-config.background-color' | translate }}
+
+ + + +
+
+
+
+
widgets.chart.chart-appearance
+
+ + {{ 'widgets.chart.vertical-grid-lines' | translate }} + +
+
+ + {{ 'widgets.chart.horizontal-grid-lines' | translate }} + +
+
+ + + + + {{ 'widget-config.legend' | translate }} + + + + + + + + +
+
+ + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.ts new file mode 100644 index 0000000000..7f529c490f --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/chart/flot-basic-config.component.ts @@ -0,0 +1,167 @@ +/// +/// Copyright © 2016-2023 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 } from '@angular/core'; +import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; +import { Store } from '@ngrx/store'; +import { AppState } from '@core/core.state'; +import { BasicWidgetConfigComponent } from '@home/components/widget/config/widget-config.component.models'; +import { WidgetConfigComponentData } from '@home/models/widget-component.models'; +import { DataKey, Datasource, WidgetConfig } from '@shared/models/widget.models'; +import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; +import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; +import { isUndefined } from '@core/utils'; +import { getTimewindowConfig } from '@home/components/widget/config/timewindow-config-panel.component'; + +@Component({ + selector: 'tb-flot-basic-config', + templateUrl: './flot-basic-config.component.html', + styleUrls: ['../basic-config.scss'] +}) +export class FlotBasicConfigComponent extends BasicWidgetConfigComponent { + + public get datasource(): Datasource { + const datasources: Datasource[] = this.flotWidgetConfigForm.get('datasources').value; + if (datasources && datasources.length) { + return datasources[0]; + } else { + return null; + } + } + + flotWidgetConfigForm: UntypedFormGroup; + + constructor(protected store: Store, + protected widgetConfigComponent: WidgetConfigComponent, + private fb: UntypedFormBuilder) { + super(store, widgetConfigComponent); + } + + protected configForm(): UntypedFormGroup { + return this.flotWidgetConfigForm; + } + + protected setupDefaults(configData: WidgetConfigComponentData) { + this.setupDefaultDatasource(configData, + [{ name: 'temperature', label: 'Temperature', type: DataKeyType.timeseries, units: '°C', decimals: 0 }]); + } + + protected onConfigSet(configData: WidgetConfigComponentData) { + this.flotWidgetConfigForm = this.fb.group({ + timewindowConfig: [getTimewindowConfig(configData.config), []], + datasources: [configData.config.datasources, []], + series: [this.getSeries(configData.config.datasources), []], + showTitle: [configData.config.showTitle, []], + title: [configData.config.title, []], + showTitleIcon: [configData.config.showTitleIcon, []], + titleIcon: [configData.config.titleIcon, []], + iconColor: [configData.config.iconColor, []], + cardButtons: [this.getCardButtons(configData.config), []], + color: [configData.config.color, []], + backgroundColor: [configData.config.backgroundColor, []], + verticalLines: [configData.config.settings?.grid?.verticalLines, []], + horizontalLines: [configData.config.settings?.grid?.horizontalLines, []], + showLegend: [configData.config.settings?.showLegend, []], + legendConfig: [configData.config.settings?.legendConfig, []], + actions: [configData.config.actions || {}, []] + }); + } + + protected prepareOutputConfig(config: any): WidgetConfigComponentData { + this.widgetConfig.config.useDashboardTimewindow = config.timewindowConfig.useDashboardTimewindow; + this.widgetConfig.config.displayTimewindow = config.timewindowConfig.displayTimewindow; + this.widgetConfig.config.timewindow = config.timewindowConfig.timewindow; + this.widgetConfig.config.datasources = config.datasources; + this.setSeries(config.series, this.widgetConfig.config.datasources); + this.widgetConfig.config.actions = config.actions; + this.widgetConfig.config.showTitle = config.showTitle; + this.widgetConfig.config.title = config.title; + this.widgetConfig.config.showTitleIcon = config.showTitleIcon; + this.widgetConfig.config.titleIcon = config.titleIcon; + this.widgetConfig.config.iconColor = config.iconColor; + this.widgetConfig.config.settings = this.widgetConfig.config.settings || {}; + this.setCardButtons(config.cardButtons, this.widgetConfig.config); + this.widgetConfig.config.backgroundColor = config.backgroundColor; + this.widgetConfig.config.settings.grid = this.widgetConfig.config.settings.grid || {}; + this.widgetConfig.config.settings.grid.verticalLines = config.verticalLines; + this.widgetConfig.config.settings.grid.horizontalLines = config.horizontalLines; + this.widgetConfig.config.settings.showLegend = config.showLegend; + this.widgetConfig.config.settings.legendConfig = config.legendConfig; + return this.widgetConfig; + } + + protected validatorTriggers(): string[] { + return ['showTitle', 'showTitleIcon', 'showLegend']; + } + + protected updateValidators(emitEvent: boolean, trigger?: string) { + const showTitle: boolean = this.flotWidgetConfigForm.get('showTitle').value; + const showTitleIcon: boolean = this.flotWidgetConfigForm.get('showTitleIcon').value; + const showLegend: boolean = this.flotWidgetConfigForm.get('showLegend').value; + if (showTitle) { + this.flotWidgetConfigForm.get('title').enable(); + this.flotWidgetConfigForm.get('showTitleIcon').enable({emitEvent: false}); + if (showTitleIcon) { + this.flotWidgetConfigForm.get('titleIcon').enable(); + this.flotWidgetConfigForm.get('iconColor').enable(); + } else { + this.flotWidgetConfigForm.get('titleIcon').disable(); + this.flotWidgetConfigForm.get('iconColor').disable(); + } + } else { + this.flotWidgetConfigForm.get('title').disable(); + this.flotWidgetConfigForm.get('showTitleIcon').disable({emitEvent: false}); + this.flotWidgetConfigForm.get('titleIcon').disable(); + this.flotWidgetConfigForm.get('iconColor').disable(); + } + if (showLegend) { + this.flotWidgetConfigForm.get('legendConfig').enable(); + } else { + this.flotWidgetConfigForm.get('legendConfig').disable(); + } + this.flotWidgetConfigForm.get('title').updateValueAndValidity({emitEvent}); + this.flotWidgetConfigForm.get('showTitleIcon').updateValueAndValidity({emitEvent: false}); + this.flotWidgetConfigForm.get('titleIcon').updateValueAndValidity({emitEvent}); + this.flotWidgetConfigForm.get('iconColor').updateValueAndValidity({emitEvent}); + this.flotWidgetConfigForm.get('legendConfig').updateValueAndValidity({emitEvent}); + } + + private getSeries(datasources?: Datasource[]): DataKey[] { + if (datasources && datasources.length) { + return datasources[0].dataKeys || []; + } + return []; + } + + private setSeries(series: DataKey[], datasources?: Datasource[]) { + if (datasources && datasources.length) { + datasources[0].dataKeys = series; + } + } + + private getCardButtons(config: WidgetConfig): string[] { + const buttons: string[] = []; + if (isUndefined(config.enableFullscreen) || config.enableFullscreen) { + buttons.push('fullscreen'); + } + return buttons; + } + + private setCardButtons(buttons: string[], config: WidgetConfig) { + config.enableFullscreen = buttons.includes('fullscreen'); + } + +} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html index 7bfa1e59b1..e8bc229488 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.html @@ -153,7 +153,7 @@
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts index 5765a9a64c..b0e52ee758 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/basic/common/data-key-row.component.ts @@ -154,8 +154,7 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan } get hasAdditionalLatestDataKeys(): boolean { - return this.widgetConfigComponent.widgetType === widgetType.timeseries && - this.widgetConfigComponent.modelValue?.typeParameters?.hasAdditionalLatestDataKeys; + return this.dataKeysPanelComponent.hasAdditionalLatestDataKeys; } get widget(): Widget { 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 171b872a0a..9091f6f895 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 @@ -100,6 +100,10 @@ export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnC @coerceBoolean() hideDataKeyColor = false; + @Input() + @coerceBoolean() + hideSourceSelection = false; + dataKeyType: DataKeyType; alarmKeys: Array; functionTypeKeys: Array; @@ -117,7 +121,7 @@ export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnC } get hasAdditionalLatestDataKeys(): boolean { - return this.widgetConfigComponent.widgetType === widgetType.timeseries && + return !this.hideSourceSelection && this.widgetConfigComponent.widgetType === widgetType.timeseries && this.widgetConfigComponent.modelValue?.typeParameters?.hasAdditionalLatestDataKeys; } diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html index 6de3c70022..95427dc8db 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html @@ -15,7 +15,7 @@ limitations under the License. --> -
@@ -54,7 +54,7 @@
widget-config.decimals-short
- +
@@ -182,14 +182,12 @@
-
-
- - -
+
+ +
diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss deleted file mode 100644 index 46659e6f4b..0000000000 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss +++ /dev/null @@ -1,107 +0,0 @@ -/** - * Copyright © 2016-2023 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'; - -:host { - .tb-datakey-config { - .fields-group { - padding: 0 16px 8px; - margin-bottom: 10px; - border: 1px groove rgba(0, 0, 0, .25); - border-radius: 4px; - - legend { - color: rgba(0, 0, 0, .7); - width: fit-content; - } - - legend + * { - display: block; - margin-top: 16px; - } - - &.fields-group-slider { - padding: 0; - - legend { - margin-left: 16px; - } - - > .tb-settings { - margin-top: 0; - padding: 0 16px 8px; - } - } - } - - .tb-hint.after-fields { - margin-top: -0.75em; - max-width: fit-content; - line-height: 15px; - } - } -} - -:host ::ng-deep { - .tb-datakey-config { - .mat-expansion-panel { - &.tb-settings { - box-shadow: none; - - .mat-content { - overflow: visible; - } - - .mat-expansion-panel-header { - padding: 0; - color: rgba(0, 0, 0, 0.87); - - &:hover { - background: none; - } - - .mat-expansion-indicator { - padding: 2px; - } - } - - &.comparison { - .mat-expansion-panel-header { - height: fit-content; - } - } - - .mat-expansion-panel-header-description { - align-items: center; - } - - > .mat-expansion-panel-content { - > .mat-expansion-panel-body { - padding: 0; - } - } - } - - .mat-expansion-panel-content { - font: inherit; - } - } - - .mat-slide { - margin: 8px 0; - } - } -} diff --git a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts index e3047f637e..f37451d32d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts @@ -57,7 +57,7 @@ import { coerceBoolean } from '@shared/decorators/coercion'; @Component({ selector: 'tb-data-key-config', templateUrl: './data-key-config.component.html', - styleUrls: ['./data-key-config.component.scss'], + styleUrls: [], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts index ae674a4d55..9900fe90f4 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts @@ -69,7 +69,7 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid } public get maxDatasources(): number { - return this.widgetConfigComponent.modelValue?.typeParameters?.maxDatasources; + return this.forceSingleDatasource ? 1 : this.widgetConfigComponent.modelValue?.typeParameters?.maxDatasources; } public get singleDatasource(): boolean { @@ -108,6 +108,10 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid @coerceBoolean() hideDataKeys = false; + @Input() + @coerceBoolean() + forceSingleDatasource = false; + @Input() configMode: WidgetConfigMode; @@ -175,13 +179,20 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid this.datasourcesMode = this.detectDatasourcesMode(datasources); let changed = false; if (datasources) { - datasources.forEach((datasource) => { + let length; + if (this.maxDatasources === -1) { + length = datasources.length; + } else { + length = Math.min(this.maxDatasources, datasources.length); + } + for (let i = 0; i < length; i++) { + const datasource = datasources[i]; if (this.basicMode && datasource.type !== this.datasourcesMode) { datasource.type = this.datasourcesMode; changed = true; } this.datasourcesFormArray.push(this.fb.control(datasource, []), {emitEvent: false}); - }); + } } if (this.singleDatasource && !this.datasourcesFormArray.length) { this.addDatasource(false); diff --git a/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts index 31436c9415..410896dd74 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/config/timewindow-config-panel.component.ts @@ -17,10 +17,11 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { WidgetConfigComponent } from '@home/components/widget/widget-config.component'; -import { widgetType } from '@shared/models/widget.models'; +import { WidgetConfig, widgetType } from '@shared/models/widget.models'; import { Timewindow } from '@shared/models/time/time.models'; import { TranslateService } from '@ngx-translate/core'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { isDefined } from '@core/utils'; export interface TimewindowConfigData { useDashboardTimewindow: boolean; @@ -28,6 +29,14 @@ export interface TimewindowConfigData { timewindow: Timewindow; } +export const getTimewindowConfig = (config: WidgetConfig): TimewindowConfigData => ({ + useDashboardTimewindow: isDefined(config.useDashboardTimewindow) ? + config.useDashboardTimewindow : true, + displayTimewindow: isDefined(config.displayTimewindow) ? + config.displayTimewindow : true, + timewindow: config.timewindow + }); + @Component({ selector: 'tb-timewindow-config-panel', templateUrl: './timewindow-config-panel.component.html', diff --git a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html index a2ed480388..1381ad31a8 100644 --- a/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/config/widget-units.component.html @@ -15,6 +15,6 @@ limitations under the License. --> - + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-key-settings.component.html index 888c400b0f..4599a12472 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-key-settings.component.html @@ -19,20 +19,20 @@
widgets.table.column-settings
-
{{ 'widgets.table.custom-title' | translate }}
+
{{ 'widgets.table.custom-title' | translate }}
{{ 'widgets.table.column-width' | translate }}
- +
{{ 'widgets.table.default-column-visibility' | translate }}
- + {{ 'widgets.table.column-visibility-visible' | translate }} @@ -48,7 +48,7 @@
{{ 'widgets.table.column-selection-to-display' | translate }}
- + {{ 'widgets.table.column-selection-to-display-enabled' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html index e53693c900..266fa4725c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/entities-table-widget-settings.component.html @@ -19,7 +19,7 @@
widgets.table.table-header
-
{{ 'widgets.table.entities-table-title' | translate }}
+
{{ 'widgets.table.entities-table-title' | translate }}
@@ -31,10 +31,10 @@
widgets.table.header-buttons
- + {{ 'widgets.table.enable-search' | translate }} - + {{ 'widgets.table.enable-select-column-display' | translate }}
@@ -42,7 +42,7 @@
widgets.table.columns
- + {{ 'widgets.table.display-entity-name' | translate }} @@ -50,7 +50,7 @@
- + {{ 'widgets.table.display-entity-label' | translate }} @@ -85,12 +85,12 @@
widgets.table.pagination
- + {{ 'widgets.table.display-pagination' | translate }}
widgets.table.default-page-size
- +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html index 0a878676ba..576cba177e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-key-settings.component.html @@ -20,7 +20,7 @@
widgets.table.column-settings
{{ 'widgets.table.default-column-visibility' | translate }}
- + {{ 'widgets.table.column-visibility-visible' | translate }} @@ -36,7 +36,7 @@
{{ 'widgets.table.column-selection-to-display' | translate }}
- + {{ 'widgets.table.column-selection-to-display-enabled' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html index dcdc8c2904..d43039ca26 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-latest-key-settings.component.html @@ -18,18 +18,18 @@
widgets.table.column-settings
- + {{ 'widgets.table.show-latest-data-column' | translate }}
widgets.table.latest-data-column-order
- +
{{ 'widgets.table.default-column-visibility' | translate }}
- + {{ 'widgets.table.column-visibility-visible' | translate }} @@ -45,7 +45,7 @@
{{ 'widgets.table.column-selection-to-display' | translate }}
- + {{ 'widgets.table.column-selection-to-display-enabled' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html index 5cbed7da88..138554c8ed 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/cards/timeseries-table-widget-settings.component.html @@ -18,25 +18,25 @@
widgets.table.table-header
- + {{ 'widgets.table.enable-sticky-header' | translate }} - + {{ 'widgets.table.enable-search' | translate }} - + {{ 'widgets.table.enable-select-column-display' | translate }}
widgets.table.columns
- + {{ 'widgets.table.display-timestamp' | translate }} - + {{ 'widgets.table.display-milliseconds' | translate }} - + {{ 'widgets.table.enable-sticky-action' | translate }} @@ -53,25 +53,25 @@
widgets.table.pagination
- + {{ 'widgets.table.display-pagination' | translate }}
widgets.table.default-page-size
- +
widgets.table.table-tabs
- + {{ 'widgets.table.use-entity-label-tab-name' | translate }}
widgets.table.rows
- + {{ 'widgets.table.hide-empty-lines' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html index 2bebfeef8a..118c41f366 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.html @@ -15,81 +15,85 @@ limitations under the License. --> -
-
- widgets.chart.common-settings - + +
+ {{ 'widgets.chart.data-is-hidden-by-default' | translate }} - - + + {{ 'widgets.chart.disable-data-hiding' | translate }} - - + + {{ 'widgets.chart.remove-from-legend' | translate }} - - + + {{ 'widgets.chart.exclude-from-stacking' | translate }} - -
-
- widgets.chart.line-settings + +
+
- - - + + {{ 'widgets.chart.show-line' | translate }} - + widget-config.advanced-settings -
- - widgets.chart.line-width - +
+
{{ 'widgets.chart.line-width' | translate }}
+ + + px - - {{ 'widgets.chart.fill-line' | translate }} - - - widgets.chart.fill-line-opacity - +
+ + {{ 'widgets.chart.fill-line' | translate }} + +
+
{{ 'widgets.chart.fill-line-opacity' | translate }}
+ + -
+
- -
- widgets.chart.points-settings +
+
- - - + + {{ 'widgets.chart.show-points' | translate }} - + widget-config.advanced-settings -
-
- - widgets.chart.points-line-width - - - - widgets.chart.points-radius - - -
- - widgets.chart.point-shape +
+
{{ 'widgets.chart.points-line-width' | translate }}
+ + + px + +
+
+
{{ 'widgets.chart.points-radius' | translate }}
+ + + px + +
+
+
{{ 'widgets.chart.point-shape' | translate }}
+ {{ 'widgets.chart.point-shape-circle' | translate }} @@ -111,19 +115,19 @@ - - -
+
+ + - -
- widgets.chart.tooltip-settings +
+
+
widgets.chart.tooltip-settings
- -
- widgets.chart.yaxis-settings - +
+
+
widgets.chart.vertical-axis
+ {{ 'widgets.chart.show-separate-axis' | translate }} - - widgets.chart.axis-title - - -
- - widgets.chart.min-scale-value - +
+
widgets.chart.axis-title
+ + - - widgets.chart.max-scale-value - +
+
+
widgets.chart.min-scale-value
+ + -
- - widgets.chart.axis-position - - - {{ 'widgets.chart.axis-position-left' | translate }} - - - {{ 'widgets.chart.axis-position-right' | translate }} - - - -
- widgets.chart.yaxis-tick-labels-settings -
- - widgets.chart.tick-step-size - +
+
+
widgets.chart.max-scale-value
+ + + +
+
+
{{ 'widgets.chart.axis-position' | translate }}
+ + + + {{ 'widgets.chart.axis-position-left' | translate }} + + + {{ 'widgets.chart.axis-position-right' | translate }} + + + +
+
+
widgets.chart.ticks
+
+
widget-config.decimals-short
+ + - - widgets.chart.number-of-decimals - +
+
+
widgets.chart.tick-step-size
+ + - +
- - -
- widgets.chart.thresholds -
-
-
- - -
-
-
- widgets.chart.no-thresholds -
-
- +
+
+
+
+
widgets.chart.thresholds
+ +
+
+
+ +
-
+
+
+
widgets.chart.comparison-settings diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.ts index b2c88e5fcb..f254eaeb2e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-key-settings.component.ts @@ -225,6 +225,7 @@ export class FlotKeySettingsComponent extends PageComponent implements OnInit, C this.flotKeySettingsFormGroup.disable({emitEvent: false}); } else { this.flotKeySettingsFormGroup.enable({emitEvent: false}); + this.updateValidators(false); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html index 353e716ad9..43382c439d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.html @@ -15,44 +15,38 @@ limitations under the License. --> - - -
- -
-
{{ thresholdText() }}
-
-
-
-
-
- - -
-
- -
- -
- -
- - widgets.chart.line-width - - - - -
+
+ + +
+
{{ thresholdText() }}
+ + + + +
+
+ + +
+ + widgets.chart.line-width + + + +
-
- - + + + +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.scss index 53eeafb799..1b4c3865ab 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.scss @@ -13,28 +13,58 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -:host { - display: block; + +.tb-flot-threshold { + display: flex; + flex-direction: row; + align-items: start; + gap: 4px; .mat-expansion-panel { box-shadow: none; - &.flot-threshold { - border: 1px groove rgba(0, 0, 0, .25); - .mat-expansion-panel-header { - padding: 0 24px 0 8px; - &.mat-expanded { - height: 48px; + border-radius: 6px; + border: 1px solid rgba(0, 0, 0, 0.12); + .mat-expansion-panel-header { + height: 56px; + border-radius: 0; + display: flex; + flex-direction: row; + align-items: stretch; + .tb-threshold-header { + flex: 1; + display: flex; + flex-direction: row; + gap: 16px; + align-items: center; + padding-left: 16px; + .mat-divider-vertical { + height: 100%; } } + .tb-threshold-text { + flex: 1; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 16px; + letter-spacing: 0.15px; + } + .mat-expansion-indicator { + margin-right: 22px; + margin-left: 22px; + margin-top: 12px; + } } - } -} - -:host ::ng-deep { - .mat-expansion-panel { - &.flot-threshold { - .mat-expansion-panel-body { - padding: 0 8px 8px; + .mat-expansion-panel-body { + padding: 0 8px 8px; + } + &.mat-expanded { + .mat-expansion-panel-header { + border-bottom: 1px solid rgba(0, 0, 0, 0.12); } } } + .mdc-icon-button { + margin-top: 4px; + color: rgba(0, 0, 0, 0.54); + } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.ts index 9b997ed424..eb55c12f86 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-threshold.component.ts @@ -15,8 +15,14 @@ /// import { ValueSourceProperty } from '@home/components/widget/lib/settings/common/value-source.component'; -import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core'; -import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms'; +import { Component, EventEmitter, forwardRef, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; +import { + ControlValueAccessor, + NG_VALUE_ACCESSOR, + UntypedFormBuilder, + UntypedFormGroup, + Validators +} from '@angular/forms'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; @@ -28,14 +34,15 @@ import { TbFlotKeyThreshold } from '@home/components/widget/lib/flot-widget.mode @Component({ selector: 'tb-flot-threshold', templateUrl: './flot-threshold.component.html', - styleUrls: ['./flot-threshold.component.scss', './../widget-settings.scss'], + styleUrls: ['./flot-threshold.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FlotThresholdComponent), multi: true } - ] + ], + encapsulation: ViewEncapsulation.None }) export class FlotThresholdComponent extends PageComponent implements OnInit, ControlValueAccessor { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html index 9baf89cbd4..e74126f309 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.html @@ -15,35 +15,33 @@ limitations under the License. --> -
-
- widgets.chart.common-settings -
- - {{ 'widgets.chart.enable-stacking-mode' | translate }} - - - {{ 'widgets.chart.enable-selection-mode' | translate }} - -
-
- - widgets.chart.line-shadow-size - + +
+
widgets.chart.common-settings
+ + {{ 'widgets.chart.enable-stacking-mode' | translate }} + + + {{ 'widgets.chart.enable-selection-mode' | translate }} + + + {{ 'widgets.chart.display-smooth-lines' | translate }} + +
+
widgets.chart.line-shadow-size
+ + - - {{ 'widgets.chart.display-smooth-lines' | translate }} - -
-
- - widgets.chart.default-bar-width - +
+
+
widgets.chart.default-bar-width
+ + - - widgets.chart.bar-alignment +
+
+
{{ 'widgets.chart.bar-alignment' | translate }}
+ {{ 'widgets.chart.bar-alignment-left' | translate }} @@ -56,211 +54,255 @@ - -
- - widgets.chart.default-font-size - +
+
+
widgets.chart.thresholds-line-width
+ + - - - - - widgets.chart.thresholds-line-width - - - -
- widget-config.legend +
+
+
{{ 'widgets.chart.default-font' | translate }}
+
+ + + px + + + + +
+
+
+
+
widget-config.legend
- + - - {{ 'widget-config.display-legend' | translate }} + + {{ 'widget-config.legend' | translate }} - + widget-config.advanced-settings - + + - -
- widgets.chart.tooltip-settings +
+
+
widgets.chart.axis
+
+
widgets.chart.vertical-axis
+
+
widgets.chart.axis-title
+ + + +
+
+
widgets.chart.min-scale-value
+ + + +
+
+
widgets.chart.max-scale-value
+ + + +
+
+
widgets.chart.ticks
+ + + + + {{ 'widgets.chart.ticks' | translate }} + + + + widget-config.advanced-settings + + + +
+
{{ 'widget-config.color' | translate }}
+
+ + + +
+
+
+
widget-config.decimals-short
+ + + +
+
+
widgets.chart.tick-step-size
+ + + +
+ + +
+
+
+
+
+
widgets.chart.horizontal-axis
+
+
widgets.chart.axis-title
+ + + +
+
+
widgets.chart.ticks
+ + + + + {{ 'widgets.chart.ticks' | translate }} + + + + widget-config.advanced-settings + + + +
+
{{ 'widget-config.color' | translate }}
+
+ + + +
+
+
+
+
+
+
+
+
widgets.chart.chart-background
+
+ + {{ 'widgets.chart.vertical-grid-lines' | translate }} + +
+
+ + {{ 'widgets.chart.horizontal-grid-lines' | translate }} + +
+
+
{{ 'widgets.chart.grid-lines-color' | translate }}
+
+ + + +
+
+
+
{{ 'widgets.chart.border' | translate }}
+
+ + + px + + + + +
+
+
+
{{ 'widgets.chart.background-color' | translate }}
+
+ + + +
+
+
+
+
widgets.chart.tooltip
- - - + + - {{ 'widgets.chart.show-tooltip' | translate }} + {{ 'widgets.chart.tooltip' | translate }} - + widget-config.advanced-settings -
- +
+ {{ 'widgets.chart.hover-individual-points' | translate }} - +
+
+ {{ 'widgets.chart.show-cumulative-values' | translate }} - +
+
+ {{ 'widgets.chart.hide-zero-false-values' | translate }} - - -
+
+ + - -
- widgets.chart.grid-settings - - {{ 'widgets.chart.show-vertical-lines' | translate }} - - - {{ 'widgets.chart.show-horizontal-lines' | translate }} - - - widgets.chart.grid-outline-border-width - - - - - - - - -
-
- widgets.chart.xaxis-settings - - widgets.chart.axis-title - - -
- widgets.chart.xaxis-tick-labels-settings - - - - - {{ 'widgets.chart.show-tick-labels' | translate }} - - - - widget-config.advanced-settings - - - - - - - -
-
-
- widgets.chart.yaxis-settings - - widgets.chart.axis-title - - -
- - widgets.chart.min-scale-value - - - - widgets.chart.max-scale-value - - -
-
- widgets.chart.yaxis-tick-labels-settings - - - - - {{ 'widgets.chart.show-tick-labels' | translate }} - - - - widget-config.advanced-settings - - - - - -
- - widgets.chart.tick-step-size - - - - widgets.chart.number-of-decimals - - -
- - -
-
-
-
-
- widgets.chart.comparison-settings +
+
+
widgets.chart.comparison-settings
- - - + + {{ 'widgets.chart.enable-comparison' | translate }} - + widget-config.advanced-settings -
- - widgets.chart.time-for-comparison +
+
{{ 'widgets.chart.time-for-comparison' | translate }}
+ {{ 'widgets.chart.time-for-comparison-previous-interval' | translate }} @@ -282,18 +324,29 @@ - - widgets.chart.custom-interval-value - +
+
+
widgets.chart.custom-interval-value
+ + -
- widgets.chart.comparison-x-axis-settings - - widgets.chart.axis-title - +
+
+
widgets.chart.comparison-x-axis-settings
+
+
widgets.chart.axis-title
+ + - - widgets.chart.axis-position +
+
+ + {{ 'widgets.chart.show-tick-labels' | translate }} + +
+
+
{{ 'widgets.chart.axis-position' | translate }}
+ {{ 'widgets.chart.axis-position-top' | translate }} @@ -303,31 +356,28 @@ - - {{ 'widgets.chart.show-tick-labels' | translate }} - - -
+
+
- -
- widgets.chart.custom-legend-settings +
+
+
widgets.chart.custom-legend-settings
- + - + {{ 'widgets.chart.enable-custom-legend' | translate }} - + widget-config.advanced-settings -
- widgets.chart.label-keys-list +
+
widgets.chart.label-keys-list
@@ -353,8 +403,8 @@
-
+
- - +
+ diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts index abcfdeebc3..46454937f6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/flot-widget-settings.component.ts @@ -284,6 +284,7 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit this.flotSettingsFormGroup.disable({emitEvent: false}); } else { this.flotSettingsFormGroup.enable({emitEvent: false}); + this.updateValidators(false); } } @@ -379,9 +380,11 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit } else { this.flotSettingsFormGroup.get('comparisonCustomIntervalValue').disable({emitEvent}); } + this.flotSettingsFormGroup.get('xaxisSecond').enable({emitEvent: false}); } else { this.flotSettingsFormGroup.get('timeForComparison').disable({emitEvent: false}); this.flotSettingsFormGroup.get('comparisonCustomIntervalValue').disable({emitEvent}); + this.flotSettingsFormGroup.get('xaxisSecond').disable({emitEvent: false}); } if (customLegendEnabled) { this.flotSettingsFormGroup.get('dataKeysListForLabels').enable({emitEvent}); @@ -392,6 +395,7 @@ export class FlotWidgetSettingsComponent extends PageComponent implements OnInit this.flotSettingsFormGroup.get('legendConfig').updateValueAndValidity({emitEvent: false}); this.flotSettingsFormGroup.get('timeForComparison').updateValueAndValidity({emitEvent: false}); this.flotSettingsFormGroup.get('comparisonCustomIntervalValue').updateValueAndValidity({emitEvent: false}); + this.flotSettingsFormGroup.get('xaxisSecond').updateValueAndValidity({emitEvent: false}); this.flotSettingsFormGroup.get('dataKeysListForLabels').updateValueAndValidity({emitEvent: false}); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.ts index 0cd2cad7c7..0cc661cb44 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/chart/label-data-key.component.ts @@ -47,7 +47,7 @@ export function labelDataKeyValidator(control: AbstractControl): ValidationError @Component({ selector: 'tb-label-data-key', templateUrl: './label-data-key.component.html', - styleUrls: ['./label-data-key.component.scss', './../widget-settings.scss'], + styleUrls: ['./label-data-key.component.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.html index f7e2234afd..70663fbad6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.html @@ -15,20 +15,21 @@ limitations under the License. --> -
-
- - legend.direction - + +
+
{{ 'legend.direction' | translate }}
+ + {{ legendDirectionTranslations.get(legendDirection[direction]) | translate }} - - legend.position - +
+
+
{{ 'legend.position' | translate }}
+ + @@ -37,28 +38,17 @@
-
- - {{ 'legend.show-min' | translate }} - - - {{ 'legend.show-max' | translate }} - -
-
- - {{ 'legend.show-avg' | translate }} - - - {{ 'legend.show-total' | translate }} - -
-
- - {{ 'legend.show-latest' | translate }} - - - {{ 'legend.sort-legend' | translate }} - +
+
legend.show-values
+ + {{ 'legend.min-option' | translate }} + {{ 'legend.max-option' | translate }} + {{ 'legend.average-option' | translate }} + {{ 'legend.total-option' | translate }} + {{ 'legend.latest-option' | translate }} +
- + + {{ 'legend.sort-legend' | translate }} + + diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.ts index c8de7872e8..15b2bbe316 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/settings/common/legend-config.component.ts @@ -15,7 +15,7 @@ /// import { Component, forwardRef, Input, OnDestroy, OnInit } from '@angular/core'; -import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR, UntypedFormBuilder, UntypedFormGroup } from '@angular/forms'; import { isDefined } from '@core/utils'; import { LegendConfig, @@ -30,7 +30,7 @@ import { Subscription } from 'rxjs'; @Component({ selector: 'tb-legend-config', templateUrl: './legend-config.component.html', - styleUrls: [], + styleUrls: ['./../widget-settings.scss'], providers: [ { provide: NG_VALUE_ACCESSOR, @@ -62,12 +62,8 @@ export class LegendConfigComponent implements OnInit, OnDestroy, ControlValueAcc this.legendConfigForm = this.fb.group({ direction: [null, []], position: [null, []], - sortDataKeys: [null, []], - showMin: [null, []], - showMax: [null, []], - showAvg: [null, []], - showTotal: [null, []], - showLatest: [null, []] + showValues: [[], []], + sortDataKeys: [null, []] }); this.legendSettingsFormDirectionChanges$ = this.legendConfigForm.get('direction').valueChanges .subscribe((direction: LegendDirection) => { @@ -121,18 +117,49 @@ export class LegendConfigComponent implements OnInit, OnDestroy, ControlValueAcc this.legendConfigForm.patchValue({ direction: legendConfig.direction, position: legendConfig.position, - sortDataKeys: isDefined(legendConfig.sortDataKeys) ? legendConfig.sortDataKeys : false, - showMin: isDefined(legendConfig.showMin) ? legendConfig.showMin : false, - showMax: isDefined(legendConfig.showMax) ? legendConfig.showMax : false, - showAvg: isDefined(legendConfig.showAvg) ? legendConfig.showAvg : false, - showTotal: isDefined(legendConfig.showTotal) ? legendConfig.showTotal : false, - showLatest: isDefined(legendConfig.showLatest) ? legendConfig.showLatest : false + showValues: this.getShowValues(legendConfig), + sortDataKeys: isDefined(legendConfig.sortDataKeys) ? legendConfig.sortDataKeys : false }, {emitEvent: false}); } this.onDirectionChanged(legendConfig.direction); } private legendConfigUpdated() { - this.propagateChange(this.legendConfigForm.value); + const configValue = this.legendConfigForm.value; + const legendConfig: Partial = { + direction: configValue.direction, + position: configValue.position, + sortDataKeys: configValue.sortDataKeys + }; + this.setShowValues(configValue.showValues, legendConfig); + this.propagateChange(legendConfig); + } + + private getShowValues(legendConfig: LegendConfig): string[] { + const showValues: string[] = []; + if (isDefined(legendConfig.showMin) && legendConfig.showMin) { + showValues.push('min'); + } + if (isDefined(legendConfig.showMax) && legendConfig.showMax) { + showValues.push('max'); + } + if (isDefined(legendConfig.showAvg) && legendConfig.showAvg) { + showValues.push('average'); + } + if (isDefined(legendConfig.showTotal) && legendConfig.showTotal) { + showValues.push('total'); + } + if (isDefined(legendConfig.showLatest) && legendConfig.showLatest) { + showValues.push('latest'); + } + return showValues; + } + + private setShowValues(showValues: string[], legendConfig: Partial) { + legendConfig.showMin = showValues.includes('min'); + legendConfig.showMax = showValues.includes('max'); + legendConfig.showAvg = showValues.includes('average'); + legendConfig.showTotal = showValues.includes('total'); + legendConfig.showLatest = showValues.includes('latest'); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html index 04c2ee467e..144d29b8b0 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/widget-config.component.html @@ -36,14 +36,16 @@ {{ 'widget-config.display-title' | translate }} -
- - widget-config.title - +
+
widget-config.title
+ + - - widget-config.title-tooltip - +
+
+
widget-config.title-tooltip
+ +
@@ -55,7 +57,7 @@ [color]="widgetSettings.get('iconColor').value" formControlName="titleIcon"> - + @@ -102,13 +104,13 @@
{{ 'widget-config.padding' | translate }}
- +
{{ 'widget-config.margin' | translate }}
- +
@@ -166,13 +168,13 @@
widget-config.order
- +
widget-config.height
- +
@@ -241,7 +243,7 @@
widget-config.limits
widget-config.data-page-size
- +
@@ -258,12 +260,12 @@
widget-config.decimals
- +
-
widget-config.no-data-display-message
+
widget-config.no-data-display-message
diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 55b377dcec..395d727841 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2782,8 +2782,14 @@ "left-side": "Left side layout" }, "legend": { - "direction": "Legend direction", - "position": "Legend position", + "direction": "Direction", + "position": "Position", + "show-values": "Show values", + "min-option": "Min", + "max-option": "Max", + "average-option": "Average", + "total-option": "Total", + "latest-option": "Latest", "sort-legend": "Sort datakeys in legend", "show-max": "Show max value", "show-min": "Show min value", @@ -4250,7 +4256,10 @@ "text": "Text", "background": "Background", "advanced-widget-style": "Advanced widget style", - "card-buttons": "Card buttons" + "card-buttons": "Card buttons", + "show-card-buttons": "Show card buttons", + "card-appearance": "Card appearance", + "color": "Color" }, "widget-type": { "import": "Import widget type", @@ -4273,10 +4282,12 @@ "bar-alignment-left": "Left", "bar-alignment-right": "Right", "bar-alignment-center": "Center", + "default-font": "Default font", "default-font-size": "Default font size", "default-font-color": "Default font color", "thresholds-line-width": "Default line width for all thresholds", "tooltip-settings": "Tooltip settings", + "tooltip": "Tooltip", "show-tooltip": "Show tooltip", "hover-individual-points": "Hover individual points", "show-cumulative-values": "Show cumulative values in stacking mode", @@ -4351,7 +4362,7 @@ "axis-position-right": "Right", "thresholds": "Thresholds", "no-thresholds": "No thresholds configured", - "add-threshold": "Add new threshold", + "add-threshold": "Add threshold", "show-values-for-comparison": "Show historical values for comparison", "comparison-values-label": "Historical values label", "threshold-settings": "Threshold settings", @@ -4372,7 +4383,23 @@ "border-color": "Border color", "legend-settings": "Legend settings", "display-legend": "Display legend", - "labels-font-color": "Labels font color" + "labels-font-color": "Labels font color", + "series": "Series", + "add-series": "Add series", + "series-settings": "Series settings", + "remove-series": "Remove series", + "no-series": "No series configured", + "no-series-error": "At least one series should be specified", + "chart-appearance": "Chart appearance", + "vertical-grid-lines": "Vertical grid lines", + "horizontal-grid-lines": "Horizontal grid lines", + "chart-background": "Chart background", + "grid-lines-color": "Grid lines color", + "border": "Border", + "axis": "Axis", + "vertical-axis": "Vertical axis", + "ticks": "Ticks", + "horizontal-axis": "Horizontal axis" }, "dashboard-state": { "dashboard-state-settings": "Dashboard state settings", @@ -5239,7 +5266,6 @@ "remove-column": "Remove column", "add-column": "Add column", "no-columns": "No columns configured", - "show-card-buttons": "Show card buttons", "columns-to-display": "Columns to display", "table-header": "Table header", "header-buttons": "Header buttons", diff --git a/ui-ngx/src/styles.scss b/ui-ngx/src/styles.scss index f4d4192122..bcedae7a1d 100644 --- a/ui-ngx/src/styles.scss +++ b/ui-ngx/src/styles.scss @@ -1212,11 +1212,11 @@ mat-label { &.tb-slide-toggle { padding: 0; gap: 0; - .tb-widget-config-panel-title { + > .tb-widget-config-panel-title { padding-top: 16px; padding-left: 16px; } - .mat-expansion-panel { + > .mat-expansion-panel { padding: 16px; .mat-expansion-panel-header { height: 32px; @@ -1232,7 +1232,7 @@ mat-label { .mat-content { overflow: visible; } - .mat-expansion-panel-header { + > .mat-expansion-panel-header { font-weight: 500; font-size: 16px; line-height: 24px; @@ -1255,12 +1255,15 @@ mat-label { padding: 2px; } } - .mat-expansion-panel-header-description { + > .mat-expansion-panel-header-description { align-items: center; } > .mat-expansion-panel-content { > .mat-expansion-panel-body { - padding: 0; + display: flex; + flex-direction: column; + gap: 16px; + padding: 16px 0 0 !important; } } .tb-json-object-panel, .tb-css-content-panel { @@ -1272,9 +1275,9 @@ mat-label { } } .mat-slide { - margin: 8px 0; - &.no-margin { - margin: 0; + margin: 0; + &.margin { + margin: 8px 0; } .mdc-form-field>label { font-weight: 400; @@ -1313,7 +1316,13 @@ mat-label { height: 56px; } .mat-mdc-form-field { - width: 80px; + width: 106px; + &.medium-width { + width: 220px; + } + } + .fixed-title-width { + min-width: 200px; } } @@ -1341,9 +1350,9 @@ mat-label { } } .mat-mdc-form-field-infix { - padding-top: 7px; - padding-bottom: 7px; - min-height: 38px; + padding-top: 8px; + padding-bottom: 8px; + min-height: 40px; width: auto; .mdc-text-field__input, .mat-mdc-select { font-weight: 400; @@ -1373,6 +1382,14 @@ mat-label { } } } + .mat-mdc-form-field-flex { + .mat-mdc-form-field-icon-suffix { + font-size: 14px; + line-height: 20px; + letter-spacing: 0.2px; + color: rgba(0, 0, 0, 0.38); + } + } } }