Browse Source

UI: Basic settings for gauge

pull/9485/head
Artem Dzhereleiko 3 years ago
parent
commit
384c5db084
  1. 30
      ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts
  2. 183
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.html
  3. 213
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.ts
  4. 154
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.html
  5. 188
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.ts
  6. 54
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/radial-gauge-basic-config.component.ts
  7. 54
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/speed-gauge-basic-config.component.ts
  8. 68
      ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/thermometer-scale-gauge-basic-config.component.ts
  9. 16
      ui-ngx/src/assets/locale/locale.constant-en_US.json

30
ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts

@ -70,6 +70,18 @@ import {
import {
ProgressBarBasicConfigComponent
} from '@home/components/widget/config/basic/cards/progress-bar-basic-config.component';
import {
RadialGaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/radial-gauge-basic-config.component';
import {
SpeedGaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/speed-gauge-basic-config.component';
import {
ThermometerScaleGaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/thermometer-scale-gauge-basic-config.component';
import {
CompassGaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/compass-gauge-basic-config.component';
@NgModule({
declarations: [
@ -91,7 +103,11 @@ import {
WindSpeedDirectionBasicConfigComponent,
SignalStrengthBasicConfigComponent,
ValueChartCardBasicConfigComponent,
ProgressBarBasicConfigComponent
ProgressBarBasicConfigComponent,
RadialGaugeBasicConfigComponent,
SpeedGaugeBasicConfigComponent,
ThermometerScaleGaugeBasicConfigComponent,
CompassGaugeBasicConfigComponent
],
imports: [
CommonModule,
@ -117,7 +133,11 @@ import {
WindSpeedDirectionBasicConfigComponent,
SignalStrengthBasicConfigComponent,
ValueChartCardBasicConfigComponent,
ProgressBarBasicConfigComponent
ProgressBarBasicConfigComponent,
RadialGaugeBasicConfigComponent,
SpeedGaugeBasicConfigComponent,
ThermometerScaleGaugeBasicConfigComponent,
CompassGaugeBasicConfigComponent
]
})
export class BasicWidgetConfigModule {
@ -137,5 +157,9 @@ export const basicWidgetConfigComponentsMap: {[key: string]: Type<IBasicWidgetCo
'tb-wind-speed-direction-basic-config': WindSpeedDirectionBasicConfigComponent,
'tb-signal-strength-basic-config': SignalStrengthBasicConfigComponent,
'tb-value-chart-card-basic-config': ValueChartCardBasicConfigComponent,
'tb-progress-bar-basic-config': ProgressBarBasicConfigComponent
'tb-progress-bar-basic-config': ProgressBarBasicConfigComponent,
'tb-radial-gauge-basic-config': RadialGaugeBasicConfigComponent,
'tb-speed-gauge-basic-config': SpeedGaugeBasicConfigComponent,
'tb-thermometer-scale-gauge-basic-config': ThermometerScaleGaugeBasicConfigComponent,
'tb-compass-gauge-basic-config': CompassGaugeBasicConfigComponent
};

183
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.html

@ -0,0 +1,183 @@
<!--
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.
-->
<ng-container [formGroup]="radialGaugeWidgetConfigForm">
<tb-timewindow-config-panel *ngIf="displayTimewindowConfig"
[onlyHistoryTimewindow]="onlyHistoryTimewindow()"
formControlName="timewindowConfig">
</tb-timewindow-config-panel>
<tb-datasources
[configMode]="basicMode"
hideDataKeyLabel
hideDataKeyColor
hideDataKeyUnits
hideDataKeyDecimals
formControlName="datasources">
</tb-datasources>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.gauge.gauge-appearance</div>
<div class="tb-form-row column-xs">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showUnitTitle">
{{ 'widgets.gauge.units-title' | translate }}
</mat-slide-toggle>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="unitTitle" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-font-settings formControlName="titleFont"
disabledLineHeight
[previewText]="radialGaugeWidgetConfigForm.get('unitTitle').value">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="titleColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widget-config.units-short</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-unit-input
formControlName="units">
</tb-unit-input>
<tb-font-settings formControlName="unitsFont"
disabledLineHeight
[previewText]="radialGaugeWidgetConfigForm.get('units').value">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="unitsColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="valueBox">
{{ 'widgets.gauge.value' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field appearance="outline" class="flex number" subscriptSizing="dynamic">
<input matInput formControlName="valueInt" type="number" min="0" max="15" step="1" placeholder="{{ 'widget-config.set' | translate }}">
<div matSuffix fxHide.lt-md translate>widget-config.decimals-suffix</div>
</mat-form-field>
<tb-font-settings formControlName="valueFont"
disabledLineHeight
[previewText]="valuePreviewFn">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="valueColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between column-xs">
<div translate>widgets.gauge.ticks</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<div class="tb-small-label" translate>widgets.gauge.min-value-short</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="minValue" type="number" step="1" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<div class="tb-small-label" translate>widgets.gauge.max-value-short</div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="maxValue" type="number" step="1" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-font-settings formControlName="numbersFont"
disabledLineHeight
[previewText]="valuePreviewFn">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="numbersColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.arrow-and-scale-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="defaultColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.plate-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorPlate">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.scale-color</div>
<tb-color-settings formControlName="highlights">
<!-- [disabledColorType]="[colorType.constant, colorType.function]"-->
</tb-color-settings>
</div>
<div class="tb-form-panel" *ngIf="gaugeType === 'thermometer'">
<div class="tb-form-panel-title" translate>widgets.gauge.progress-bar</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.progress-bar-color-start</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorBarProgress">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.progress-bar-color-end</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorBarProgressEnd">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.bar-stroke-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorBarStroke">
</tb-color-input>
</div>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.card-appearance</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="backgroundColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between column-lt-md">
<div translate>widget-config.show-card-buttons</div>
<mat-chip-listbox multiple formControlName="cardButtons">
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.card-border-radius' | translate }}</div>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="borderRadius" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
</div>
<tb-widget-actions-panel
formControlName="actions">
</tb-widget-actions-panel>
</ng-container>

213
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/analog-gauge-basic-config.component.ts

@ -0,0 +1,213 @@
///
/// 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 { ChangeDetectorRef, Component, Injector } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } 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,
datasourcesHasAggregation,
datasourcesHasOnlyComparisonAggregation,
WidgetConfig,
} from '@shared/models/widget.models';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import {
getTimewindowConfig,
setTimewindowConfig
} from '@home/components/widget/config/timewindow-config-panel.component';
import { formatValue, isDefinedAndNotNull, isUndefined } from '@core/utils';
import {
ColorType,
DateFormatProcessor,
DateFormatSettings,
getLabel,
setLabel
} from '@shared/models/widget-settings.models';
import {
valueCardDefaultSettings,
ValueCardLayout,
valueCardLayoutImages,
valueCardLayouts,
valueCardLayoutTranslations,
ValueCardWidgetSettings
} from '@home/components/widget/lib/cards/value-card-widget.models';
// @Component({
// selector: 'tb-radial-gauge-basic-config',
// templateUrl: './analog-gauge-basic-config.component.html',
// styleUrls: ['../basic-config.scss']
// })
export class GaugeBasicConfigComponent extends BasicWidgetConfigComponent {
public get displayTimewindowConfig(): boolean {
const datasources = this.radialGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasAggregation(datasources);
}
public onlyHistoryTimewindow(): boolean {
const datasources = this.radialGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasOnlyComparisonAggregation(datasources);
}
colorType = ColorType;
radialGaugeWidgetConfigForm: UntypedFormGroup;
valuePreviewFn = this._valuePreviewFn.bind(this);
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent);
}
protected configForm(): UntypedFormGroup {
return this.radialGaugeWidgetConfigForm;
}
protected setupDefaults(configData: WidgetConfigComponentData, key?: DataKey[]) {
this.setupDefaultDatasource(configData, key);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
this.radialGaugeWidgetConfigForm = this.fb.group({
timewindowConfig: [getTimewindowConfig(configData.config), []],
datasources: [configData.config.datasources, []],
showUnitTitle: [configData.config.settings?.showUnitTitle, []],
unitTitle: [configData.config.settings?.unitTitle, []],
titleFont: [configData.config.settings?.titleFont, []],
titleColor: [configData.config.settings?.titleFont.color, []],
units: [configData.config.units, []],
unitsFont: [configData.config.settings?.unitsFont, []],
unitsColor: [configData.config.settings?.unitsFont.color, []],
valueBox: [configData.config.settings?.valueBox, []],
valueInt: [configData.config.settings?.valueInt, []],
valueFont: [configData.config.settings?.valueFont, []],
valueColor: [configData.config.settings?.valueFont.color, []],
minValue: [configData.config.settings?.minValue, []],
maxValue: [configData.config.settings?.maxValue, []],
numbersFont: [configData.config.settings?.numbersFont, []],
numbersColor: [configData.config.settings?.numbersFont.color, []],
colorBarStroke: [configData.config.settings?.colorBarStroke, []],
defaultColor: [configData.config.settings?.defaultColor, []],
colorPlate: [configData.config.settings?.colorPlate, []],
highlights: [{
type: 'range',
rangeList: configData.config.settings?.highlights
}, []],
cardButtons: [this.getCardButtons(configData.config), []],
borderRadius: [configData.config.borderRadius, []],
backgroundColor: [configData.config.backgroundColor, []],
actions: [configData.config.actions || {}, []]
});
}
protected prepareOutputConfig(config: any): WidgetConfigComponentData {
setTimewindowConfig(this.widgetConfig.config, config.timewindowConfig);
this.widgetConfig.config.datasources = config.datasources;
// setLabel(config.label, this.widgetConfig.config.datasources);
this.widgetConfig.config.actions = config.actions;
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.showUnitTitle = config.showUnitTitle;
this.widgetConfig.config.settings.unitTitle = config.unitTitle;
this.widgetConfig.config.settings.titleFont = config.titleFont;
this.widgetConfig.config.settings.titleFont.color = config.titleColor;
this.widgetConfig.config.units = config.units;
this.widgetConfig.config.settings.unitsFont = config.unitsFont;
this.widgetConfig.config.settings.unitsFont.color = config.unitsColor;
this.widgetConfig.config.settings.valueBox = config.valueBox;
this.widgetConfig.config.settings.valueInt = config.valueInt;
this.widgetConfig.config.settings.valueFont = config.valueFont;
this.widgetConfig.config.settings.valueFont.color = config.valueColor;
this.widgetConfig.config.settings.minValue = config.minValue;
this.widgetConfig.config.settings.maxValue = config.maxValue;
this.widgetConfig.config.settings.numbersFont = config.numbersFont;
this.widgetConfig.config.settings.numbersFont.color = config.numbersColor;
this.widgetConfig.config.settings.defaultColor = config.defaultColor;
this.widgetConfig.config.settings.colorPlate = config.colorPlate;
this.widgetConfig.config.settings.highlights = config.highlights.rangeList;
return this.widgetConfig;
}
protected validatorTriggers(): string[] {
return ['showUnitTitle', 'valueBox'];
}
protected updateValidators(emitEvent: boolean, trigger?: string) {
const showUnitTitle: boolean = this.radialGaugeWidgetConfigForm.get('showUnitTitle').value;
const valueBox: boolean = this.radialGaugeWidgetConfigForm.get('valueBox').value;
if (showUnitTitle) {
this.radialGaugeWidgetConfigForm.get('unitTitle').enable();
this.radialGaugeWidgetConfigForm.get('titleFont').enable();
this.radialGaugeWidgetConfigForm.get('titleColor').enable();
} else {
this.radialGaugeWidgetConfigForm.get('unitTitle').disable();
this.radialGaugeWidgetConfigForm.get('titleFont').disable();
this.radialGaugeWidgetConfigForm.get('titleColor').disable();
}
if (valueBox) {
this.radialGaugeWidgetConfigForm.get('valueInt').enable();
this.radialGaugeWidgetConfigForm.get('valueFont').enable();
this.radialGaugeWidgetConfigForm.get('valueColor').enable();
} else {
this.radialGaugeWidgetConfigForm.get('valueInt').disable();
this.radialGaugeWidgetConfigForm.get('valueFont').disable();
this.radialGaugeWidgetConfigForm.get('valueColor').disable();
}
this.radialGaugeWidgetConfigForm.get('unitTitle').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('titleFont').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('titleColor').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('valueInt').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('valueFont').updateValueAndValidity({emitEvent});
this.radialGaugeWidgetConfigForm.get('valueColor').updateValueAndValidity({emitEvent});
}
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');
}
private _valuePreviewFn(): string {
const units: string = this.radialGaugeWidgetConfigForm.get('units').value;
return formatValue(22, 0, units, true);
}
}

154
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.html

@ -0,0 +1,154 @@
<!--
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.
-->
<ng-container [formGroup]="compassGaugeWidgetConfigForm">
<tb-timewindow-config-panel *ngIf="displayTimewindowConfig"
[onlyHistoryTimewindow]="onlyHistoryTimewindow()"
formControlName="timewindowConfig">
</tb-timewindow-config-panel>
<tb-datasources
[configMode]="basicMode"
hideDataKeyLabel
hideDataKeyColor
hideDataKeyUnits
hideDataKeyDecimals
formControlName="datasources">
</tb-datasources>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.appearance</div>
<div class="tb-form-row column-xs">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="showTitle">
{{ 'widget-config.title' | translate }}
</mat-slide-toggle>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="title" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
<tb-font-settings formControlName="titleFont"
clearButton
[previewText]="compassGaugeWidgetConfigForm.get('title').value"
[initialPreviewStyle]="widgetConfig.config.titleStyle">
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="titleColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<mat-slide-toggle class="mat-slide" formControlName="showTitleIcon">
{{ 'widget-config.icon' | translate }}
</mat-slide-toggle>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-material-icon-select asBoxInput
iconClearButton
[color]="compassGaugeWidgetConfigForm.get('iconColor').value"
formControlName="titleIcon">
</tb-material-icon-select>
<tb-color-input asBoxInput
colorClearButton
formControlName="iconColor">
</tb-color-input>
</div>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.gauge.compass-appearance</div>
<div class="tb-form-row">
<div class="fixed-title-width" translate>widgets.gauge.labels</div>
<div fxFlex fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-string-items-list
style="display: flex"
fxFlex
appearance="outline"
subscriptSizing="dynamic"
editable
formControlName="majorTicks">
</tb-string-items-list>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.label-style</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="8px">
<tb-font-settings formControlName="majorTickFont"
disabledLineHeight>
</tb-font-settings>
<tb-color-input asBoxInput
colorClearButton
formControlName="majorTickColor">
</tb-color-input>
</div>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.major-ticks-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorMajorTicks">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.minor-ticks-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorMinorTicks">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.needle-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorNeedle">
</tb-color-input>
</div>
<div class="tb-form-row space-between">
<div translate>widgets.gauge.plate-color</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="colorPlate">
</tb-color-input>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.card-appearance</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.background-color' | translate }}</div>
<tb-color-input asBoxInput
colorClearButton
formControlName="backgroundColor">
</tb-color-input>
</div>
<div class="tb-form-row space-between column-lt-md">
<div translate>widget-config.show-card-buttons</div>
<mat-chip-listbox multiple formControlName="cardButtons">
<mat-chip-option value="fullscreen">{{ 'fullscreen.fullscreen' | translate }}</mat-chip-option>
</mat-chip-listbox>
</div>
<div class="tb-form-row space-between">
<div>{{ 'widget-config.card-border-radius' | translate }}</div>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="borderRadius" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
</div>
<tb-widget-actions-panel
formControlName="actions">
</tb-widget-actions-panel>
</ng-container>

188
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/compass-gauge-basic-config.component.ts

@ -0,0 +1,188 @@
///
/// 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 { ChangeDetectorRef, Component, Injector } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } 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,
datasourcesHasAggregation,
datasourcesHasOnlyComparisonAggregation,
WidgetConfig,
} from '@shared/models/widget.models';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import {
getTimewindowConfig,
setTimewindowConfig
} from '@home/components/widget/config/timewindow-config-panel.component';
import { formatValue, isDefinedAndNotNull, isUndefined } from '@core/utils';
import {
ColorType,
DateFormatProcessor,
DateFormatSettings,
getLabel,
setLabel
} from '@shared/models/widget-settings.models';
import {
valueCardDefaultSettings,
ValueCardLayout,
valueCardLayoutImages,
valueCardLayouts,
valueCardLayoutTranslations,
ValueCardWidgetSettings
} from '@home/components/widget/lib/cards/value-card-widget.models';
@Component({
selector: 'tb-compass-gauge-basic-config',
templateUrl: './compass-gauge-basic-config.component.html',
styleUrls: ['../basic-config.scss']
})
export class CompassGaugeBasicConfigComponent extends BasicWidgetConfigComponent {
public get displayTimewindowConfig(): boolean {
const datasources = this.compassGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasAggregation(datasources);
}
public onlyHistoryTimewindow(): boolean {
const datasources = this.compassGaugeWidgetConfigForm.get('datasources').value;
return datasourcesHasOnlyComparisonAggregation(datasources);
}
compassGaugeWidgetConfigForm: UntypedFormGroup;
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent);
}
protected configForm(): UntypedFormGroup {
return this.compassGaugeWidgetConfigForm;
}
protected setupDefaults(configData: WidgetConfigComponentData) {
this.setupDefaultDatasource(configData, [{ name: 'direction', label: 'Direction', type: DataKeyType.timeseries }]);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
this.compassGaugeWidgetConfigForm = this.fb.group({
timewindowConfig: [getTimewindowConfig(configData.config), []],
datasources: [configData.config.datasources, []],
showTitle: [configData.config.showTitle, []],
title: [configData.config.title, []],
titleFont: [configData.config.titleFont, []],
titleColor: [configData.config.titleColor, []],
showTitleIcon: [configData.config.showTitleIcon, []],
titleIcon: [configData.config.titleIcon, []],
iconColor: [configData.config.iconColor, []],
majorTicks: [configData.config.settings?.majorTicks, []],
majorTickFont: [configData.config.settings?.majorTickFont, []],
majorTickColor: [configData.config.settings?.majorTickFont.color, []],
colorMajorTicks: [configData.config.settings?.colorMajorTicks, []],
colorMinorTicks: [configData.config.settings?.colorMinorTicks, []],
colorPlate: [configData.config.settings?.colorPlate, []],
colorNeedle: [configData.config.settings?.colorNeedle, []],
cardButtons: [this.getCardButtons(configData.config), []],
borderRadius: [configData.config.borderRadius, []],
backgroundColor: [configData.config.backgroundColor, []],
actions: [configData.config.actions || {}, []]
});
}
protected prepareOutputConfig(config: any): WidgetConfigComponentData {
setTimewindowConfig(this.widgetConfig.config, config.timewindowConfig);
this.widgetConfig.config.datasources = config.datasources;
this.widgetConfig.config.actions = config.actions;
this.widgetConfig.config.showTitle = config.showTitle;
this.widgetConfig.config.title = config.title;
this.widgetConfig.config.titleFont = config.titleFont;
this.widgetConfig.config.titleColor = config.titleColor;
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.majorTicks = config.majorTicks;
this.widgetConfig.config.settings.majorTickFont = config.majorTickFont;
this.widgetConfig.config.settings.majorTickFont.color = config.majorTickColor;
this.widgetConfig.config.settings.colorMajorTicks = config.colorMajorTicks;
this.widgetConfig.config.settings.colorMinorTicks = config.colorMinorTicks;
this.widgetConfig.config.settings.colorPlate = config.colorPlate;
this.widgetConfig.config.settings.colorNeedle = config.colorNeedle;
return this.widgetConfig;
}
protected validatorTriggers(): string[] {
return ['showTitle', 'showTitleIcon'];
}
protected updateValidators(emitEvent: boolean, trigger?: string) {
const showTitle: boolean = this.compassGaugeWidgetConfigForm.get('showTitle').value;
const showTitleIcon: boolean = this.compassGaugeWidgetConfigForm.get('showTitleIcon').value;
if (showTitle) {
this.compassGaugeWidgetConfigForm.get('title').enable();
this.compassGaugeWidgetConfigForm.get('titleFont').enable();
this.compassGaugeWidgetConfigForm.get('titleColor').enable();
this.compassGaugeWidgetConfigForm.get('showTitleIcon').enable({emitEvent: false});
if (showTitleIcon) {
this.compassGaugeWidgetConfigForm.get('titleIcon').enable();
this.compassGaugeWidgetConfigForm.get('iconColor').enable();
} else {
this.compassGaugeWidgetConfigForm.get('titleIcon').disable();
this.compassGaugeWidgetConfigForm.get('iconColor').disable();
}
} else {
this.compassGaugeWidgetConfigForm.get('title').disable();
this.compassGaugeWidgetConfigForm.get('titleFont').disable();
this.compassGaugeWidgetConfigForm.get('titleColor').disable();
this.compassGaugeWidgetConfigForm.get('showTitleIcon').disable({emitEvent: false});
this.compassGaugeWidgetConfigForm.get('titleIcon').disable();
this.compassGaugeWidgetConfigForm.get('iconColor').disable();
}
this.compassGaugeWidgetConfigForm.get('title').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('titleFont').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('titleColor').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('showTitleIcon').updateValueAndValidity({emitEvent: false});
this.compassGaugeWidgetConfigForm.get('titleIcon').updateValueAndValidity({emitEvent});
this.compassGaugeWidgetConfigForm.get('iconColor').updateValueAndValidity({emitEvent});
}
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');
}
}

54
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/radial-gauge-basic-config.component.ts

@ -0,0 +1,54 @@
///
/// 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 { WidgetSettings } from '@shared/models/widget.models';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
AnalogueGaugeWidgetSettingsComponent
} from '@home/components/widget/lib/settings/gauge/analogue-gauge-widget-settings.component';
import {
GaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/analog-gauge-basic-config.component';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
@Component({
selector: 'tb-radial-gauge-basic-config',
templateUrl: './analog-gauge-basic-config.component.html',
styleUrls: ['../basic-config.scss']
})
export class RadialGaugeBasicConfigComponent extends GaugeBasicConfigComponent {
gaugeType = 'radial';
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent, fb);
}
protected setupDefaults(configData: WidgetConfigComponentData) {
return super.setupDefaults(configData, [{ name: 'temperature', label: 'Temperature', type: DataKeyType.timeseries }]);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
super.onConfigSet(configData);
}
}

54
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/speed-gauge-basic-config.component.ts

@ -0,0 +1,54 @@
///
/// 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 { WidgetSettings } from '@shared/models/widget.models';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
AnalogueGaugeWidgetSettingsComponent
} from '@home/components/widget/lib/settings/gauge/analogue-gauge-widget-settings.component';
import {
GaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/analog-gauge-basic-config.component';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
@Component({
selector: 'tb-speed-gauge-basic-config',
templateUrl: './analog-gauge-basic-config.component.html',
styleUrls: ['../basic-config.scss']
})
export class SpeedGaugeBasicConfigComponent extends GaugeBasicConfigComponent {
gaugeType = 'speed';
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent, fb);
}
protected setupDefaults(configData: WidgetConfigComponentData) {
return super.setupDefaults(configData, [{ name: 'speed', label: 'Speed', type: DataKeyType.timeseries }]);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
super.onConfigSet(configData);
}
}

68
ui-ngx/src/app/modules/home/components/widget/config/basic/gauge/thermometer-scale-gauge-basic-config.component.ts

@ -0,0 +1,68 @@
///
/// 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 { WidgetSettings } from '@shared/models/widget.models';
import { UntypedFormBuilder, Validators } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
AnalogueGaugeWidgetSettingsComponent
} from '@home/components/widget/lib/settings/gauge/analogue-gauge-widget-settings.component';
import {
GaugeBasicConfigComponent
} from '@home/components/widget/config/basic/gauge/analog-gauge-basic-config.component';
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
@Component({
selector: 'tb-thermometer-scale-gauge-basic-config',
templateUrl: './analog-gauge-basic-config.component.html',
styleUrls: ['../basic-config.scss']
})
export class ThermometerScaleGaugeBasicConfigComponent extends GaugeBasicConfigComponent {
gaugeType = 'thermometer';
constructor(protected store: Store<AppState>,
protected widgetConfigComponent: WidgetConfigComponent,
protected fb: UntypedFormBuilder) {
super(store, widgetConfigComponent, fb);
}
protected setupDefaults(configData: WidgetConfigComponentData) {
return super.setupDefaults(configData, [{ name: 'temperature', label: 'Temperature', type: DataKeyType.timeseries }]);
}
protected onConfigSet(configData: WidgetConfigComponentData) {
super.onConfigSet(configData);
this.radialGaugeWidgetConfigForm.addControl('colorBarStroke',
this.fb.control(configData.config.settings?.colorBarStroke, []));
this.radialGaugeWidgetConfigForm.addControl('colorBarProgress',
this.fb.control(configData.config.settings?.colorBarProgress, []));
this.radialGaugeWidgetConfigForm.addControl('colorBarProgressEnd',
this.fb.control(configData.config.settings?.colorBarProgressEnd, []));
}
protected prepareOutputConfig(config): WidgetConfigComponentData {
const outputConfig = super.prepareOutputConfig(config);
this.widgetConfig.config.settings.colorBarStroke = config.colorBarStroke;
this.widgetConfig.config.settings.colorBarProgress = config.colorBarProgress;
this.widgetConfig.config.settings.colorBarProgressEnd = config.colorBarProgressEnd;
return outputConfig;
}
}

16
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -5011,6 +5011,7 @@
"title-icon": "Title icon",
"display-icon": "Display title icon",
"card-icon": "Card icon",
"icon": "Icon",
"icon-color": "Icon color",
"icon-size": "Icon size",
"advanced-settings": "Advanced settings",
@ -5357,6 +5358,8 @@
"ticks-settings": "Ticks settings",
"min-value": "Minimum value",
"max-value": "Maximum value",
"min-value-short": "min",
"max-value-short": "max",
"start-ticks-angle": "Start ticks angle",
"ticks-angle": "Ticks angle",
"major-ticks-count": "Major ticks count",
@ -5416,6 +5419,8 @@
"bar-background-color": "Gauge bar background color",
"bar-background-color-end": "Bar background color - end gradient",
"progress-bar-color": "Progress bar color",
"progress-bar": "Progress bar",
"progress-bar-color-start": "Progress bar color - start gradient",
"progress-bar-color-end": "Progress bar color - end gradient",
"major-ticks-names": "Major ticks names",
"show-stroke-ticks": "Show ticks stroke",
@ -5465,7 +5470,16 @@
"tick-color": "Tick color",
"tick-values": "Tick values",
"no-tick-values": "No tick values configured",
"add-tick-value": "Add tick value"
"add-tick-value": "Add tick value",
"gauge-appearance": "Gauge appearance",
"units-title": "Units title",
"value": "Value",
"ticks": "Ticks",
"arrow-and-scale-color": "Arrow and scale default color",
"scale-color": "Scale colors",
"compass-appearance": "Compass appearance",
"labels": "Labels",
"label-style": "Label style"
},
"gpio": {
"pin": "Pin",

Loading…
Cancel
Save