Browse Source

UI: Add advanced settings for action button. Update Get attribute/time-series value action to always subscribe for updates.

pull/10132/head
Igor Kulikov 3 years ago
parent
commit
42edd481e7
  1. 4
      application/src/main/data/json/system/widget_types/action_button.json
  2. 42
      ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts
  3. 12
      ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts
  4. 6
      ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts
  5. 51
      ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.html
  6. 70
      ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.ts
  7. 10
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.html
  8. 8
      ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts
  9. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.ts
  10. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts
  11. 9
      ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts
  12. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts
  13. 2
      ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts
  14. 20
      ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts
  15. 18
      ui-ngx/src/app/shared/models/action-widget-settings.models.ts
  16. 2
      ui-ngx/src/assets/locale/locale.constant-en_US.json

4
application/src/main/data/json/system/widget_types/action_button.json

@ -11,10 +11,10 @@
"resources": [],
"templateHtml": "<tb-action-button-widget \n [ctx]=\"ctx\"\n [widgetTitlePanel]=\"widgetTitlePanel\">\n</tb-action-button-widget>",
"templateCss": "#container tb-markdown-widget {\n height: 100%;\n display: block;\n}\n\n#container tb-markdown-widget .tb-markdown-view {\n height: 100%;\n overflow: auto;\n}\n",
"controllerScript": "self.onInit = function() {\n self.ctx.$scope.actionWidget.onInit();\n}\n\nself.actionSources = function() {\n return {\n 'click': {\n name: 'widget-action.click',\n multiple: false\n }\n };\n}\n\nself.typeParameters = function() {\n return {\n dataKeysOptional: true,\n datasourcesOptional: true,\n maxDatasources: 1,\n maxDataKeys: 0,\n singleEntity: true,\n previewWidth: '200px',\n previewHeight: '80px',\n embedTitlePanel: true,\n overflowVisible: true\n };\n}\n\nself.onDestroy = function() {\n}\n\n",
"controllerScript": "self.onInit = function() {\n self.ctx.$scope.actionWidget.onInit();\n}\n\nself.actionSources = function() {\n return {\n 'click': {\n name: 'widget-action.click',\n multiple: false\n }\n };\n}\n\nself.typeParameters = function() {\n return {\n dataKeysOptional: true,\n datasourcesOptional: true,\n maxDatasources: 1,\n maxDataKeys: 0,\n singleEntity: true,\n previewWidth: '200px',\n previewHeight: '80px',\n embedTitlePanel: true,\n overflowVisible: true,\n hideDataSettings: true\n };\n}\n\nself.onDestroy = function() {\n}\n\n",
"settingsSchema": "",
"dataKeySettingsSchema": "",
"settingsDirective": "",
"settingsDirective": "tb-action-button-widget-settings",
"hasBasicMode": true,
"basicModeDirective": "tb-action-button-basic-config",
"defaultConfig": "{\"datasources\":[],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":false,\"backgroundColor\":\"#FFFFFF01\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"0px\",\"settings\":{},\"title\":\"Action button\",\"showTitleIcon\":false,\"iconColor\":\"rgba(0, 0, 0, 0.87)\",\"iconSize\":\"24px\",\"titleTooltip\":\"\",\"dropShadow\":false,\"enableFullscreen\":false,\"widgetStyle\":{},\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400},\"showLegend\":false,\"useDashboardTimewindow\":true,\"displayTimewindow\":true,\"widgetCss\":\"\",\"pageSize\":1024,\"noDataDisplayMessage\":\"\",\"borderRadius\":\"4px\",\"configMode\":\"basic\"}"

42
ui-ngx/src/app/modules/home/components/widget/lib/action/action-widget.models.ts

@ -31,7 +31,6 @@ import {
DataToValueSettings,
DataToValueType,
GetAttributeValueSettings,
GetTelemetryValueSettings,
GetValueAction,
GetValueSettings,
RpcSettings,
@ -405,7 +404,7 @@ export class ExecuteRpcValueGetter<V> extends ValueGetter<V> {
}
}
export abstract class TelemetryValueGetter<V, S extends GetTelemetryValueSettings> extends ValueGetter<V> {
export abstract class TelemetryValueGetter<V, S extends TelemetryValueSettings> extends ValueGetter<V> {
protected targetEntityId: EntityId;
private telemetrySubscriber: TelemetrySubscriber;
@ -428,11 +427,7 @@ export abstract class TelemetryValueGetter<V, S extends GetTelemetryValueSetting
if (err) {
return throwError(() => err);
}
if (this.getTelemetryValueSettings().subscribeForUpdates) {
return this.subscribeForTelemetryValue();
} else {
return this.doGetTelemetryValue();
}
return this.subscribeForTelemetryValue();
} else {
return of(null);
}
@ -464,8 +459,6 @@ export abstract class TelemetryValueGetter<V, S extends GetTelemetryValueSetting
protected abstract getTelemetryValueSettings(): S;
protected abstract doGetTelemetryValue(): Observable<V>;
destroy() {
if (this.telemetrySubscriber) {
this.telemetrySubscriber.unsubscribe();
@ -492,17 +485,9 @@ export class AttributeValueGetter<V> extends TelemetryValueGetter<V, GetAttribut
return this.getTelemetryValueSettings().scope;
}
protected doGetTelemetryValue(): Observable<V> {
const getAttributeValueSettings = this.getTelemetryValueSettings();
return this.ctx.attributeService.getEntityAttributes(this.targetEntityId,
getAttributeValueSettings.scope, [getAttributeValueSettings.key], {ignoreLoading: true, ignoreErrors: true}).pipe(
map((data) => data.find(attr => attr.key === getAttributeValueSettings.key)?.value)
);
}
}
export class TimeSeriesValueGetter<V> extends TelemetryValueGetter<V, GetTelemetryValueSettings> {
export class TimeSeriesValueGetter<V> extends TelemetryValueGetter<V, TelemetryValueSettings> {
constructor(protected ctx: WidgetContext,
protected settings: GetValueSettings<V>,
@ -511,28 +496,9 @@ export class TimeSeriesValueGetter<V> extends TelemetryValueGetter<V, GetTelemet
super(ctx, settings, valueType, valueObserver);
}
protected getTelemetryValueSettings(): GetTelemetryValueSettings {
protected getTelemetryValueSettings(): TelemetryValueSettings {
return this.settings.getTimeSeries;
}
protected doGetTelemetryValue(): Observable<V> {
const getTelemetryValueSettings = this.getTelemetryValueSettings();
return this.ctx.attributeService.getEntityTimeseriesLatest(this.targetEntityId,
[getTelemetryValueSettings.key], true, {ignoreLoading: true, ignoreErrors: true})
.pipe(
map((data) => {
let value: any = null;
if (data[getTelemetryValueSettings.key]) {
const dataSet = data[getTelemetryValueSettings.key];
if (dataSet.length) {
value = dataSet[0].value;
}
}
return value;
})
);
}
}
export class ExecuteRpcValueSetter<V> extends ValueSetter<V> {

12
ui-ngx/src/app/modules/home/components/widget/lib/button/action-button-widget.models.ts

@ -33,12 +33,10 @@ export const actionButtonDefaultSettings: ActionButtonWidgetSettings = {
defaultValue: false,
getAttribute: {
key: 'state',
scope: null,
subscribeForUpdates: false
scope: null
},
getTimeSeries: {
key: 'state',
subscribeForUpdates: false
key: 'state'
},
dataToValue: {
type: DataToValueType.NONE,
@ -51,12 +49,10 @@ export const actionButtonDefaultSettings: ActionButtonWidgetSettings = {
defaultValue: false,
getAttribute: {
key: 'state',
scope: null,
subscribeForUpdates: false
scope: null
},
getTimeSeries: {
key: 'state',
subscribeForUpdates: false
key: 'state'
},
dataToValue: {
type: DataToValueType.NONE,

6
ui-ngx/src/app/modules/home/components/widget/lib/rpc/single-switch-widget.models.ts

@ -93,12 +93,10 @@ export const singleSwitchDefaultSettings: SingleSwitchWidgetSettings = {
},
getAttribute: {
key: 'state',
scope: null,
subscribeForUpdates: false
scope: null
},
getTimeSeries: {
key: 'state',
subscribeForUpdates: false
key: 'state'
},
dataToValue: {
type: DataToValueType.NONE,

51
ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.html

@ -0,0 +1,51 @@
<!--
Copyright © 2016-2024 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ng-container [formGroup]="actionButtonWidgetSettingsForm">
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widgets.action-button.behavior</div>
<div class="tb-form-row">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{'widgets.button-state.activated-state-hint' | translate}}" translate>widgets.button-state.activated-state</div>
<tb-get-value-action-settings fxFlex
panelTitle="widgets.button-state.activated-state"
[valueType]="valueType.BOOLEAN"
stateLabel="widgets.button-state.activated"
[aliasController]="aliasController"
[targetDevice]="targetDevice"
[widgetType]="widgetType"
formControlName="activatedState"></tb-get-value-action-settings>
</div>
<div class="tb-form-row">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{'widgets.button-state.disabled-state-hint' | translate}}" translate>widgets.button-state.disabled-state</div>
<tb-get-value-action-settings fxFlex
panelTitle="widgets.button-state.disabled-state"
[valueType]="valueType.BOOLEAN"
stateLabel="widgets.button-state.disabled"
[aliasController]="aliasController"
[targetDevice]="targetDevice"
[widgetType]="widgetType"
formControlName="disabledState"></tb-get-value-action-settings>
</div>
</div>
<div class="tb-form-panel">
<div class="tb-form-panel-title" translate>widget-config.appearance</div>
<tb-widget-button-appearance
[borderRadius]="borderRadius"
formControlName="appearance">
</tb-widget-button-appearance>
</div>
</ng-container>

70
ui-ngx/src/app/modules/home/components/widget/lib/settings/button/action-button-widget-settings.component.ts

@ -0,0 +1,70 @@
///
/// Copyright © 2016-2024 The Thingsboard Authors
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
import { Component } from '@angular/core';
import { TargetDevice, WidgetSettings, WidgetSettingsComponent, widgetType } from '@shared/models/widget.models';
import { UntypedFormBuilder, UntypedFormGroup } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import { ValueType } from '@shared/models/constants';
import { getTargetDeviceFromDatasources } from '@shared/models/widget-settings.models';
import { actionButtonDefaultSettings } from '@home/components/widget/lib/button/action-button-widget.models';
@Component({
selector: 'tb-action-button-widget-settings',
templateUrl: './action-button-widget-settings.component.html',
styleUrls: ['./../widget-settings.scss']
})
export class ActionButtonWidgetSettingsComponent extends WidgetSettingsComponent {
get targetDevice(): TargetDevice {
const datasources = this.widgetConfig?.config?.datasources;
return getTargetDeviceFromDatasources(datasources);
}
get widgetType(): widgetType {
return this.widgetConfig?.widgetType;
}
get borderRadius(): string {
return this.widgetConfig?.config?.borderRadius;
}
valueType = ValueType;
actionButtonWidgetSettingsForm: UntypedFormGroup;
constructor(protected store: Store<AppState>,
private fb: UntypedFormBuilder) {
super(store);
}
protected settingsForm(): UntypedFormGroup {
return this.actionButtonWidgetSettingsForm;
}
protected defaultSettings(): WidgetSettings {
return {...actionButtonDefaultSettings};
}
protected onSettingsSet(settings: WidgetSettings) {
this.actionButtonWidgetSettingsForm = this.fb.group({
activatedState: [settings.activatedState, []],
disabledState: [settings.disabledState, []],
appearance: [settings.appearance, []]
});
}
}

10
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.html

@ -84,11 +84,6 @@
[attributeScope]="getValueSettingsFormGroup.get('getAttribute').get('scope').value">
</tb-device-key-autocomplete>
</div>
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="subscribeForUpdates">
<span tb-hint-tooltip-icon="{{'widgets.value-action.subscribe-for-updates-hint' | translate}}">{{ 'widgets.value-action.subscribe-for-updates' | translate }}</span>
</mat-slide-toggle>
</div>
</ng-container>
</ng-template>
<ng-template [ngSwitchCase]="getValueAction.GET_TIME_SERIES">
@ -106,11 +101,6 @@
[keyType]="dataKeyType.timeseries">
</tb-device-key-autocomplete>
</div>
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="subscribeForUpdates">
<span tb-hint-tooltip-icon="{{'widgets.value-action.subscribe-for-updates-hint' | translate}}">{{ 'widgets.value-action.subscribe-for-updates' | translate }}</span>
</mat-slide-toggle>
</div>
</ng-container>
</ng-template>
</ng-container>

8
ui-ngx/src/app/modules/home/components/widget/lib/settings/common/action/get-value-action-settings-panel.component.ts

@ -24,7 +24,7 @@ import { merge } from 'rxjs';
import {
DataToValueType,
GetValueAction,
getValueActions, getValueActionsByWidgetType,
getValueActionsByWidgetType,
getValueActionTranslations,
GetValueSettings
} from '@shared/models/action-widget-settings.models';
@ -117,12 +117,10 @@ export class GetValueActionSettingsPanelComponent extends PageComponent implemen
}),
getAttribute: this.fb.group({
scope: [this.getValueSettings?.getAttribute?.scope, []],
key: [this.getValueSettings?.getAttribute?.key, [Validators.required]],
subscribeForUpdates: [this.getValueSettings?.getAttribute?.subscribeForUpdates, []]
key: [this.getValueSettings?.getAttribute?.key, [Validators.required]]
}),
getTimeSeries: this.fb.group({
key: [this.getValueSettings?.getTimeSeries?.key, [Validators.required]],
subscribeForUpdates: [this.getValueSettings?.getTimeSeries?.subscribeForUpdates, []]
key: [this.getValueSettings?.getTimeSeries?.key, [Validators.required]]
}),
dataToValue: this.fb.group({
type: [this.getValueSettings?.dataToValue?.type, [Validators.required]],

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/control/led-indicator-widget-settings.component.ts

@ -32,7 +32,7 @@ export class LedIndicatorWidgetSettingsComponent extends WidgetSettingsComponent
functionScopeVariables = this.widgetService.getWidgetScopeVariables();
get targetDevice(): TargetDevice {
return this.widget?.config?.targetDevice;
return this.widgetConfig?.config?.targetDevice;
}
dataKeyType = DataKeyType;

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/control/round-switch-widget-settings.component.ts

@ -37,7 +37,7 @@ export class RoundSwitchWidgetSettingsComponent extends WidgetSettingsComponent
}
get targetDevice(): TargetDevice {
return this.widget?.config?.targetDevice;
return this.widgetConfig?.config?.targetDevice;
}
protected settingsForm(): UntypedFormGroup {

9
ui-ngx/src/app/modules/home/components/widget/lib/settings/control/single-switch-widget-settings.component.ts

@ -20,7 +20,8 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms
import { Store } from '@ngrx/store';
import { AppState } from '@core/core.state';
import {
singleSwitchDefaultSettings, singleSwitchLayoutImages,
singleSwitchDefaultSettings,
singleSwitchLayoutImages,
singleSwitchLayouts,
singleSwitchLayoutTranslations
} from '@home/components/widget/lib/rpc/single-switch-widget.models';
@ -34,11 +35,11 @@ import { ValueType } from '@shared/models/constants';
export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent {
get targetDevice(): TargetDevice {
return this.widget?.config?.targetDevice;
return this.widgetConfig?.config?.targetDevice;
}
get widgetType(): widgetType {
return this.widget?.type;
return this.widgetConfig?.widgetType;
}
singleSwitchLayouts = singleSwitchLayouts;
@ -156,6 +157,4 @@ export class SingleSwitchWidgetSettingsComponent extends WidgetSettingsComponent
this.singleSwitchWidgetSettingsForm.get('offLabelColor').disable();
}
}
protected readonly ValueType = ValueType;
}

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/control/slide-toggle-widget-settings.component.ts

@ -37,7 +37,7 @@ export class SlideToggleWidgetSettingsComponent extends WidgetSettingsComponent
}
get targetDevice(): TargetDevice {
return this.widget?.config?.targetDevice;
return this.widgetConfig?.config?.targetDevice;
}
protected settingsForm(): UntypedFormGroup {

2
ui-ngx/src/app/modules/home/components/widget/lib/settings/control/switch-control-widget-settings.component.ts

@ -37,7 +37,7 @@ export class SwitchControlWidgetSettingsComponent extends WidgetSettingsComponen
}
get targetDevice(): TargetDevice {
return this.widget?.config?.targetDevice;
return this.widgetConfig?.config?.targetDevice;
}
protected settingsForm(): UntypedFormGroup {

20
ui-ngx/src/app/modules/home/components/widget/lib/settings/widget-settings.module.ts

@ -15,7 +15,9 @@
///
import { NgModule, Type } from '@angular/core';
import { QrCodeWidgetSettingsComponent } from '@home/components/widget/lib/settings/cards/qrcode-widget-settings.component';
import {
QrCodeWidgetSettingsComponent
} from '@home/components/widget/lib/settings/cards/qrcode-widget-settings.component';
import { CommonModule } from '@angular/common';
import { SharedModule } from '@shared/shared.module';
import { SharedHomeComponentsModule } from '@home/components/shared-home-components.module';
@ -33,7 +35,9 @@ import {
MarkdownWidgetSettingsComponent
} from '@home/components/widget/lib/settings/cards/markdown-widget-settings.component';
import { LabelWidgetLabelComponent } from '@home/components/widget/lib/settings/cards/label-widget-label.component';
import { LabelWidgetSettingsComponent } from '@home/components/widget/lib/settings/cards/label-widget-settings.component';
import {
LabelWidgetSettingsComponent
} from '@home/components/widget/lib/settings/cards/label-widget-settings.component';
import {
SimpleCardWidgetSettingsComponent
} from '@home/components/widget/lib/settings/cards/simple-card-widget-settings.component';
@ -311,6 +315,9 @@ import {
import {
SingleSwitchWidgetSettingsComponent
} from '@home/components/widget/lib/settings/control/single-switch-widget-settings.component';
import {
ActionButtonWidgetSettingsComponent
} from '@home/components/widget/lib/settings/button/action-button-widget-settings.component';
@NgModule({
declarations: [
@ -424,7 +431,8 @@ import {
DoughnutWidgetSettingsComponent,
RangeChartWidgetSettingsComponent,
BarChartWithLabelsWidgetSettingsComponent,
SingleSwitchWidgetSettingsComponent
SingleSwitchWidgetSettingsComponent,
ActionButtonWidgetSettingsComponent
],
imports: [
CommonModule,
@ -543,7 +551,8 @@ import {
DoughnutWidgetSettingsComponent,
RangeChartWidgetSettingsComponent,
BarChartWithLabelsWidgetSettingsComponent,
SingleSwitchWidgetSettingsComponent
SingleSwitchWidgetSettingsComponent,
ActionButtonWidgetSettingsComponent
]
})
export class WidgetSettingsModule {
@ -629,5 +638,6 @@ export const widgetSettingsComponentsMap: {[key: string]: Type<IWidgetSettingsCo
'tb-doughnut-widget-settings': DoughnutWidgetSettingsComponent,
'tb-range-chart-widget-settings': RangeChartWidgetSettingsComponent,
'tb-bar-chart-with-labels-widget-settings': BarChartWithLabelsWidgetSettingsComponent,
'tb-single-switch-widget-settings': SingleSwitchWidgetSettingsComponent
'tb-single-switch-widget-settings': SingleSwitchWidgetSettingsComponent,
'tb-action-button-widget-settings': ActionButtonWidgetSettingsComponent
};

18
ui-ngx/src/app/shared/models/action-widget-settings.models.ts

@ -54,11 +54,7 @@ export interface TelemetryValueSettings {
key: string;
}
export interface GetTelemetryValueSettings extends TelemetryValueSettings {
subscribeForUpdates: boolean;
}
export interface GetAttributeValueSettings extends GetTelemetryValueSettings {
export interface GetAttributeValueSettings extends TelemetryValueSettings {
scope: AttributeScope | null;
}
@ -86,7 +82,7 @@ export interface GetValueSettings<V> extends ValueActionSettings {
defaultValue: V;
executeRpc?: RpcSettings;
getAttribute: GetAttributeValueSettings;
getTimeSeries: GetTelemetryValueSettings;
getTimeSeries: TelemetryValueSettings;
dataToValue: DataToValueSettings;
}
@ -133,13 +129,3 @@ export interface SetValueSettings extends ValueActionSettings {
putTimeSeries: TelemetryValueSettings;
valueToData: ValueToDataSettings;
}
/*export interface RpcStateBehaviourSettings<V> {
initialState: RpcInitialStateSettings<V>;
updateStateByValue: (value: V) => RpcUpdateStateSettings;
}
export interface RpcStateWidgetSettings<V> {
initialState: RpcInitialStateSettings<V>;
background: BackgroundSettings;
}*/

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

@ -6561,8 +6561,6 @@
"attribute-key-required": "Attribute key is required.",
"time-series-key": "Time-series key",
"time-series-key-required": "Time-series key is required.",
"subscribe-for-updates": "Subscribe for updates",
"subscribe-for-updates-hint": "Subscribe for updates",
"action-result-converter": "Action result converter",
"converter-none": "None",
"converter-function": "Function",

Loading…
Cancel
Save