Browse Source

UI: Implement widgets config basic mode. Widgets config minor refactoring.

pull/8708/head
Igor Kulikov 3 years ago
parent
commit
1fe00ac46a
  1. 42
      ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html
  2. 58
      ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts
  3. 0
      ui-ngx/src/app/modules/home/components/widget/config/basic/basic-config.scss
  4. 2
      ui-ngx/src/app/modules/home/components/widget/config/basic/basic-widget-config.module.ts
  5. 86
      ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html
  6. 110
      ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts
  7. 0
      ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.html
  8. 0
      ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts
  9. 4
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.html
  10. 0
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.scss
  11. 4
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts
  12. 8
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html
  13. 0
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss
  14. 17
      ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts
  15. 6
      ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.html
  16. 0
      ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.models.ts
  17. 0
      ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss
  18. 24
      ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts
  19. 0
      ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html
  20. 0
      ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts
  21. 0
      ui-ngx/src/app/modules/home/components/widget/config/datasource.component.scss
  22. 21
      ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts
  23. 0
      ui-ngx/src/app/modules/home/components/widget/config/datasources.component.html
  24. 0
      ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss
  25. 17
      ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts
  26. 6
      ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts
  27. 0
      ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts
  28. 45
      ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss
  29. 0
      ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.html
  30. 0
      ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.scss
  31. 25
      ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.ts
  32. 0
      ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.html
  33. 0
      ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.scss
  34. 0
      ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.ts
  35. 31
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.html
  36. 259
      ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts

42
ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.html

@ -1,42 +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.
-->
<ng-container [formGroup]="simpleCardWidgetConfigForm" >
<tb-datasources
[configMode]="basicMode"
formControlName="datasources">
</tb-datasources>
<div class="tb-widget-config-panel">
<div class="tb-widget-config-panel-title" translate>widget-config.appearance</div>
<div class="tb-widget-config-row space-between">
<div translate>widgets.simple-card.label-position</div>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="labelPosition">
<mat-option [value]="'left'">
{{ 'widgets.simple-card.label-position-left' | translate }}
</mat-option>
<mat-option [value]="'top'">
{{ 'widgets.simple-card.label-position-top' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<tb-widget-actions-panel
formControlName="actions">
</tb-widget-actions-panel>
</ng-container>

58
ui-ngx/src/app/modules/home/components/widget/basic-config/cards/simple-card-basic-config.component.ts

@ -1,58 +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 { 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/widget-config.component.models';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
@Component({
selector: 'tb-simple-card-basic-config',
templateUrl: './simple-card-basic-config.component.html',
styleUrls: ['../basic-config.scss', '../../widget-config.scss']
})
export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent {
simpleCardWidgetConfigForm: UntypedFormGroup;
constructor(protected store: Store<AppState>,
private fb: UntypedFormBuilder) {
super(store);
}
protected configForm(): UntypedFormGroup {
return this.simpleCardWidgetConfigForm;
}
protected onConfigSet(configData: WidgetConfigComponentData) {
this.simpleCardWidgetConfigForm = this.fb.group({
datasources: [configData.config.datasources, []],
labelPosition: [configData.config.settings?.labelPosition, []],
actions: [configData.config.actions || {}, []]
});
}
protected prepareOutputConfig(config: any): WidgetConfigComponentData {
this.widgetConfig.config.datasources = this.simpleCardWidgetConfigForm.value.datasources;
this.widgetConfig.config.actions = this.simpleCardWidgetConfigForm.value.actions;
this.widgetConfig.config.settings = this.widgetConfig.config.settings || {};
this.widgetConfig.config.settings.labelPosition = this.simpleCardWidgetConfigForm.value.labelPosition;
return this.widgetConfig;
}
}

0
ui-ngx/src/app/modules/home/components/widget/basic-config/basic-config.scss → ui-ngx/src/app/modules/home/components/widget/config/basic/basic-config.scss

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

@ -24,7 +24,7 @@ import {
} from '@home/components/widget/basic-config/cards/simple-card-basic-config.component'; } from '@home/components/widget/basic-config/cards/simple-card-basic-config.component';
import { import {
WidgetActionsPanelComponent WidgetActionsPanelComponent
} from '@home/components/widget/basic-config/action/widget-actions-panel.component'; } from '@home/components/widget/basic-config/common/widget-actions-panel.component';
@NgModule({ @NgModule({
declarations: [ declarations: [

86
ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.html

@ -0,0 +1,86 @@
<!--
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]="simpleCardWidgetConfigForm">
<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-widget-config-panel">
<div class="tb-widget-config-panel-title" translate>widget-config.appearance</div>
<div class="tb-widget-config-row">
<div translate>widgets.simple-card.label</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic">
<input matInput formControlName="label" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-widget-config-row space-between">
<div translate>widgets.simple-card.label-position</div>
<mat-form-field appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="labelPosition">
<mat-option [value]="'left'">
{{ 'widgets.simple-card.label-position-left' | translate }}
</mat-option>
<mat-option [value]="'top'">
{{ 'widgets.simple-card.label-position-top' | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="tb-widget-config-row space-between">
<div translate>widget-config.units-short</div>
<mat-form-field appearance="outline" class="center" subscriptSizing="dynamic">
<input matInput formControlName="units" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-widget-config-row space-between">
<div translate>widget-config.decimals-short</div>
<mat-form-field appearance="outline" class="center number" subscriptSizing="dynamic">
<input matInput formControlName="decimals" type="number" min="0" max="15" step="1" placeholder="{{ 'widget-config.set' | translate }}">
</mat-form-field>
</div>
<div class="tb-widget-config-row space-between same-padding">
<div>{{ 'widget-config.text-color' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="color">
</tb-color-input>
</div>
</div>
<div class="tb-widget-config-row space-between same-padding">
<div>{{ 'widget-config.background' | translate }}</div>
<div fxLayout="row" fxLayoutAlign="start center" fxLayoutGap="16px">
<mat-divider vertical></mat-divider>
<tb-color-input asBoxInput
formControlName="backgroundColor">
</tb-color-input>
</div>
</div>
</div>
<tb-widget-actions-panel
formControlName="actions">
</tb-widget-actions-panel>
</ng-container>

110
ui-ngx/src/app/modules/home/components/widget/config/basic/cards/simple-card-basic-config.component.ts

@ -0,0 +1,110 @@
///
/// 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/widget-config.component.models';
import { WidgetConfigComponentData } from '@home/models/widget-component.models';
import {
Datasource,
datasourcesHasAggregation,
datasourcesHasOnlyComparisonAggregation
} from '@shared/models/widget.models';
@Component({
selector: 'tb-simple-card-basic-config',
templateUrl: './simple-card-basic-config.component.html',
styleUrls: ['../basic-config.scss', '../../widget-config.scss']
})
export class SimpleCardBasicConfigComponent extends BasicWidgetConfigComponent {
public get displayTimewindowConfig(): boolean {
const datasources = this.simpleCardWidgetConfigForm.get('datasources').value;
return datasourcesHasAggregation(datasources);
}
public onlyHistoryTimewindow(): boolean {
const datasources = this.simpleCardWidgetConfigForm.get('datasources').value;
return datasourcesHasOnlyComparisonAggregation(datasources);
}
simpleCardWidgetConfigForm: UntypedFormGroup;
constructor(protected store: Store<AppState>,
private fb: UntypedFormBuilder) {
super(store);
}
protected configForm(): UntypedFormGroup {
return this.simpleCardWidgetConfigForm;
}
protected onConfigSet(configData: WidgetConfigComponentData) {
this.simpleCardWidgetConfigForm = this.fb.group({
timewindowConfig: [{
useDashboardTimewindow: configData.config.useDashboardTimewindow,
displayTimewindow: configData.config.useDashboardTimewindow,
timewindow: configData.config.timewindow
}, []],
datasources: [configData.config.datasources, []],
label: [this.getDataKeyLabel(configData.config.datasources), []],
labelPosition: [configData.config.settings?.labelPosition, []],
units: [configData.config.units, []],
decimals: [configData.config.decimals, []],
color: [configData.config.color, []],
backgroundColor: [configData.config.backgroundColor, []],
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.setDataKeyLabel(config.label, this.widgetConfig.config.datasources);
this.widgetConfig.config.actions = config.actions;
this.widgetConfig.config.units = config.units;
this.widgetConfig.config.decimals = config.decimals;
this.widgetConfig.config.color = config.color;
this.widgetConfig.config.backgroundColor = config.backgroundColor;
this.widgetConfig.config.settings = this.widgetConfig.config.settings || {};
this.widgetConfig.config.settings.labelPosition = config.labelPosition;
return this.widgetConfig;
}
private getDataKeyLabel(datasources?: Datasource[]): string {
if (datasources && datasources.length) {
const dataKeys = datasources[0].dataKeys;
if (dataKeys && dataKeys.length) {
return dataKeys[0].label;
}
}
return '';
}
private setDataKeyLabel(label: string, datasources?: Datasource[]) {
if (datasources && datasources.length) {
const dataKeys = datasources[0].dataKeys;
if (dataKeys && dataKeys.length) {
dataKeys[0].label = label;
}
}
}
}

0
ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.html → ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.html

0
ui-ngx/src/app/modules/home/components/widget/basic-config/action/widget-actions-panel.component.ts → ui-ngx/src/app/modules/home/components/widget/config/basic/common/widget-actions-panel.component.ts

4
ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.html → ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.html

@ -40,6 +40,10 @@
[widgetType]="data.widgetType" [widgetType]="data.widgetType"
[showPostProcessing]="data.showPostProcessing" [showPostProcessing]="data.showPostProcessing"
[callbacks]="data.callbacks" [callbacks]="data.callbacks"
[hideDataKeyLabel]="data.hideDataKeyLabel"
[hideDataKeyColor]="data.hideDataKeyColor"
[hideDataKeyUnits]="data.hideDataKeyUnits"
[hideDataKeyDecimals]="data.hideDataKeyDecimals"
formControlName="dataKey"> formControlName="dataKey">
</tb-data-key-config> </tb-data-key-config>
</div> </div>

0
ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.scss → ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.scss

4
ui-ngx/src/app/modules/home/components/widget/data-key-config-dialog.component.ts → ui-ngx/src/app/modules/home/components/widget/config/data-key-config-dialog.component.ts

@ -40,6 +40,10 @@ export interface DataKeyConfigDialogData {
entityAliasId?: string; entityAliasId?: string;
showPostProcessing?: boolean; showPostProcessing?: boolean;
callbacks?: DataKeysCallbacks; callbacks?: DataKeysCallbacks;
hideDataKeyLabel: boolean;
hideDataKeyColor: boolean;
hideDataKeyUnits: boolean;
hideDataKeyDecimals: boolean;
} }
@Component({ @Component({

8
ui-ngx/src/app/modules/home/components/widget/data-key-config.component.html → ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.html

@ -40,11 +40,11 @@
</mat-autocomplete> </mat-autocomplete>
</mat-form-field> </mat-form-field>
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px"> <div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px">
<mat-form-field fxFlex class="mat-block"> <mat-form-field *ngIf="!hideDataKeyLabel" fxFlex class="mat-block">
<mat-label translate>datakey.label</mat-label> <mat-label translate>datakey.label</mat-label>
<input matInput formControlName="label" required> <input matInput formControlName="label" required>
</mat-form-field> </mat-form-field>
<tb-color-input fxFlex <tb-color-input *ngIf="!hideDataKeyColor" fxFlex
required required
label="{{'datakey.color' | translate}}" label="{{'datakey.color' | translate}}"
icon="format_color_fill" icon="format_color_fill"
@ -53,11 +53,11 @@
</tb-color-input> </tb-color-input>
</div> </div>
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px" *ngIf="modelValue.type !== dataKeyTypes.alarm"> <div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px" *ngIf="modelValue.type !== dataKeyTypes.alarm">
<mat-form-field fxFlex> <mat-form-field *ngIf="!hideDataKeyUnits" fxFlex>
<mat-label translate>datakey.units</mat-label> <mat-label translate>datakey.units</mat-label>
<input matInput formControlName="units"> <input matInput formControlName="units">
</mat-form-field> </mat-form-field>
<mat-form-field fxFlex> <mat-form-field *ngIf="!hideDataKeyDecimals" fxFlex>
<mat-label translate>datakey.decimals</mat-label> <mat-label translate>datakey.decimals</mat-label>
<input matInput formControlName="decimals" type="number" min="0" max="15" step="1"> <input matInput formControlName="decimals" type="number" min="0" max="15" step="1">
</mat-form-field> </mat-form-field>

0
ui-ngx/src/app/modules/home/components/widget/data-key-config.component.scss → ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.scss

17
ui-ngx/src/app/modules/home/components/widget/data-key-config.component.ts → ui-ngx/src/app/modules/home/components/widget/config/data-key-config.component.ts

@ -52,6 +52,7 @@ import { Dashboard } from '@shared/models/dashboard.models';
import { IAliasController } from '@core/api/widget-api.models'; import { IAliasController } from '@core/api/widget-api.models';
import { aggregationTranslations, AggregationType, ComparisonDuration } from '@shared/models/time/time.models'; import { aggregationTranslations, AggregationType, ComparisonDuration } from '@shared/models/time/time.models';
import { genNextLabel } from '@core/utils'; import { genNextLabel } from '@core/utils';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({ @Component({
selector: 'tb-data-key-config', selector: 'tb-data-key-config',
@ -120,6 +121,22 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con
@Input() @Input()
showPostProcessing = true; showPostProcessing = true;
@Input()
@coerceBoolean()
hideDataKeyLabel = false;
@Input()
@coerceBoolean()
hideDataKeyColor = false;
@Input()
@coerceBoolean()
hideDataKeyUnits = false;
@Input()
@coerceBoolean()
hideDataKeyDecimals = false;
@ViewChild('keyInput') keyInput: ElementRef; @ViewChild('keyInput') keyInput: ElementRef;
@ViewChild('funcBodyEdit') funcBodyEdit: JsFuncComponent; @ViewChild('funcBodyEdit') funcBodyEdit: JsFuncComponent;

6
ui-ngx/src/app/modules/home/components/widget/data-keys.component.html → ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.html

@ -62,16 +62,16 @@
matTooltip="{{'datakey.timeseries' | translate }}" matTooltip="{{'datakey.timeseries' | translate }}"
matTooltipPosition="above">timeline</mat-icon> matTooltipPosition="above">timeline</mat-icon>
</ng-container> </ng-container>
<span *ngIf="key.label !== key.name">{{key.label}}</span> <span *ngIf="!hideDataKeyLabel && key.label !== key.name">{{key.label}}</span>
</div> </div>
<div *ngIf="key.label !== key.name" class="tb-chip-separator">: </div> <div *ngIf="!hideDataKeyLabel && key.label !== key.name" class="tb-chip-separator">: </div>
<div class="tb-chip-label"> <div class="tb-chip-label">
<strong> <strong>
<ng-container *ngTemplateOutlet="keyName; context:{key: key}"></ng-container> <ng-container *ngTemplateOutlet="keyName; context:{key: key}"></ng-container>
</strong> </strong>
</div> </div>
</div> </div>
<div style="padding: 3px;"> <div *ngIf="!hideDataKeyColor" style="padding: 3px;">
<div class="tb-color-preview small box" (click)="showColorPicker(key)"> <div class="tb-color-preview small box" (click)="showColorPicker(key)">
<div class="tb-color-result" [ngStyle]="{background: key.color}"></div> <div class="tb-color-result" [ngStyle]="{background: key.color}"></div>
</div> </div>

0
ui-ngx/src/app/modules/home/components/widget/data-keys.component.models.ts → ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.models.ts

0
ui-ngx/src/app/modules/home/components/widget/data-keys.component.scss → ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.scss

24
ui-ngx/src/app/modules/home/components/widget/data-keys.component.ts → ui-ngx/src/app/modules/home/components/widget/config/data-keys.component.ts

@ -68,6 +68,7 @@ import { AggregationType } from '@shared/models/time/time.models';
import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive'; import { DndDropEvent } from 'ngx-drag-drop/lib/dnd-dropzone.directive';
import { moveItemInArray } from '@angular/cdk/drag-drop'; import { moveItemInArray } from '@angular/cdk/drag-drop';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean } from '@shared/decorators/coercion';
import { DatasourceComponent } from '@home/components/widget/datasource.component';
@Component({ @Component({
selector: 'tb-data-keys', selector: 'tb-data-keys',
@ -88,6 +89,22 @@ import { coerceBoolean } from '@shared/decorators/coercion';
}) })
export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChanges, ErrorStateMatcher { export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChanges, ErrorStateMatcher {
public get hideDataKeyLabel(): boolean {
return this.datasourceComponent.hideDataKeyLabel;
}
public get hideDataKeyColor(): boolean {
return this.datasourceComponent.hideDataKeyColor;
}
public get hideDataKeyUnits(): boolean {
return this.datasourceComponent.hideDataKeyUnits;
}
public get hideDataKeyDecimals(): boolean {
return this.datasourceComponent.hideDataKeyDecimals;
}
datasourceTypes = DatasourceType; datasourceTypes = DatasourceType;
widgetTypes = widgetType; widgetTypes = widgetType;
dataKeyTypes = DataKeyType; dataKeyTypes = DataKeyType;
@ -188,6 +205,7 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
constructor(private store: Store<AppState>, constructor(private store: Store<AppState>,
@SkipSelf() private errorStateMatcher: ErrorStateMatcher, @SkipSelf() private errorStateMatcher: ErrorStateMatcher,
private datasourceComponent: DatasourceComponent,
public translate: TranslateService, public translate: TranslateService,
private utils: UtilsService, private utils: UtilsService,
private dialogs: DialogService, private dialogs: DialogService,
@ -480,7 +498,11 @@ export class DataKeysComponent implements ControlValueAccessor, OnInit, OnChange
deviceId: this.deviceId, deviceId: this.deviceId,
entityAliasId: this.entityAliasId, entityAliasId: this.entityAliasId,
showPostProcessing: this.widgetType !== widgetType.alarm, showPostProcessing: this.widgetType !== widgetType.alarm,
callbacks: this.callbacks callbacks: this.callbacks,
hideDataKeyLabel: this.hideDataKeyLabel,
hideDataKeyColor: this.hideDataKeyColor,
hideDataKeyUnits: this.hideDataKeyUnits,
hideDataKeyDecimals: this.hideDataKeyDecimals
} }
}).afterClosed().subscribe((updatedDataKey) => { }).afterClosed().subscribe((updatedDataKey) => {
if (updatedDataKey) { if (updatedDataKey) {

0
ui-ngx/src/app/modules/home/components/widget/datasource.component.html → ui-ngx/src/app/modules/home/components/widget/config/datasource.component.html

0
ui-ngx/src/app/modules/home/components/widget/datasource.component.models.ts → ui-ngx/src/app/modules/home/components/widget/config/datasource.component.models.ts

0
ui-ngx/src/app/modules/home/components/widget/datasource.component.scss → ui-ngx/src/app/modules/home/components/widget/config/datasource.component.scss

21
ui-ngx/src/app/modules/home/components/widget/datasource.component.ts → ui-ngx/src/app/modules/home/components/widget/config/datasource.component.ts

@ -14,7 +14,7 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { Component, forwardRef, Input, OnInit, Optional } from '@angular/core';
import { import {
ControlValueAccessor, ControlValueAccessor,
NG_VALIDATORS, NG_VALIDATORS,
@ -41,6 +41,7 @@ import { EntityAliasSelectCallbacks } from '@home/components/alias/entity-alias-
import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models'; import { FilterSelectCallbacks } from '@home/components/filter/filter-select.component.models';
import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models';
import { EntityType } from '@shared/models/entity-type.models'; import { EntityType } from '@shared/models/entity-type.models';
import { DatasourcesComponent } from '@home/components/widget/datasources.component';
@Component({ @Component({
selector: 'tb-datasource', selector: 'tb-datasource',
@ -122,6 +123,22 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida
return this.widgetConfigComponent.widget; return this.widgetConfigComponent.widget;
} }
public get hideDataKeyLabel(): boolean {
return this.datasourcesComponent?.hideDataKeyLabel;
}
public get hideDataKeyColor(): boolean {
return this.datasourcesComponent?.hideDataKeyColor;
}
public get hideDataKeyUnits(): boolean {
return this.datasourcesComponent?.hideDataKeyUnits;
}
public get hideDataKeyDecimals(): boolean {
return this.datasourcesComponent?.hideDataKeyDecimals;
}
@Input() @Input()
disabled: boolean; disabled: boolean;
@ -138,6 +155,8 @@ export class DatasourceComponent implements ControlValueAccessor, OnInit, Valida
private propagateChange = (_val: any) => {}; private propagateChange = (_val: any) => {};
constructor(private fb: UntypedFormBuilder, constructor(private fb: UntypedFormBuilder,
@Optional()
private datasourcesComponent: DatasourcesComponent,
private widgetConfigComponent: WidgetConfigComponent) { private widgetConfigComponent: WidgetConfigComponent) {
} }

0
ui-ngx/src/app/modules/home/components/widget/datasources.component.html → ui-ngx/src/app/modules/home/components/widget/config/datasources.component.html

0
ui-ngx/src/app/modules/home/components/widget/datasources.component.scss → ui-ngx/src/app/modules/home/components/widget/config/datasources.component.scss

17
ui-ngx/src/app/modules/home/components/widget/datasources.component.ts → ui-ngx/src/app/modules/home/components/widget/config/datasources.component.ts

@ -41,6 +41,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
import { UtilsService } from '@core/services/utils.service'; import { UtilsService } from '@core/services/utils.service';
import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models'; import { DataKeysCallbacks } from '@home/components/widget/data-keys.component.models';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { coerceBoolean } from '@shared/decorators/coercion';
@Component({ @Component({
selector: 'tb-datasources', selector: 'tb-datasources',
@ -87,6 +88,22 @@ export class DatasourcesComponent implements ControlValueAccessor, OnInit, Valid
@Input() @Input()
disabled: boolean; disabled: boolean;
@Input()
@coerceBoolean()
hideDataKeyLabel = false;
@Input()
@coerceBoolean()
hideDataKeyColor = false;
@Input()
@coerceBoolean()
hideDataKeyUnits = false;
@Input()
@coerceBoolean()
hideDataKeyDecimals = false;
@Input() @Input()
configMode: WidgetConfigMode; configMode: WidgetConfigMode;

6
ui-ngx/src/app/modules/home/components/widget/widget-config-components.module.ts → ui-ngx/src/app/modules/home/components/widget/config/widget-config-components.module.ts

@ -18,6 +18,7 @@ import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { SharedModule } from '@app/shared/shared.module'; import { SharedModule } from '@app/shared/shared.module';
import { AlarmFilterConfigComponent } from '@home/components/alarm/alarm-filter-config.component'; import { AlarmFilterConfigComponent } from '@home/components/alarm/alarm-filter-config.component';
import { AlarmAssigneeSelectComponent } from '@home/components/alarm/alarm-assignee-select.component';
import { DataKeysComponent } from '@home/components/widget/data-keys.component'; import { DataKeysComponent } from '@home/components/widget/data-keys.component';
import { DataKeyConfigDialogComponent } from '@home/components/widget/data-key-config-dialog.component'; import { DataKeyConfigDialogComponent } from '@home/components/widget/data-key-config-dialog.component';
import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component'; import { DataKeyConfigComponent } from '@home/components/widget/data-key-config.component';
@ -27,10 +28,12 @@ import { EntityAliasSelectComponent } from '@home/components/alias/entity-alias-
import { FilterSelectComponent } from '@home/components/filter/filter-select.component'; import { FilterSelectComponent } from '@home/components/filter/filter-select.component';
import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module'; import { WidgetSettingsModule } from '@home/components/widget/lib/settings/widget-settings.module';
import { WidgetSettingsComponent } from '@home/components/widget/widget-settings.component'; import { WidgetSettingsComponent } from '@home/components/widget/widget-settings.component';
import { TimewindowConfigPanelComponent } from '@home/components/widget/timewindow-config-panel.component';
@NgModule({ @NgModule({
declarations: declarations:
[ [
AlarmAssigneeSelectComponent,
AlarmFilterConfigComponent, AlarmFilterConfigComponent,
DataKeysComponent, DataKeysComponent,
DataKeyConfigDialogComponent, DataKeyConfigDialogComponent,
@ -39,6 +42,7 @@ import { WidgetSettingsComponent } from '@home/components/widget/widget-settings
DatasourcesComponent, DatasourcesComponent,
EntityAliasSelectComponent, EntityAliasSelectComponent,
FilterSelectComponent, FilterSelectComponent,
TimewindowConfigPanelComponent,
WidgetSettingsComponent WidgetSettingsComponent
], ],
imports: [ imports: [
@ -47,6 +51,7 @@ import { WidgetSettingsComponent } from '@home/components/widget/widget-settings
WidgetSettingsModule WidgetSettingsModule
], ],
exports: [ exports: [
AlarmAssigneeSelectComponent,
AlarmFilterConfigComponent, AlarmFilterConfigComponent,
DataKeysComponent, DataKeysComponent,
DataKeyConfigDialogComponent, DataKeyConfigDialogComponent,
@ -55,6 +60,7 @@ import { WidgetSettingsComponent } from '@home/components/widget/widget-settings
DatasourcesComponent, DatasourcesComponent,
EntityAliasSelectComponent, EntityAliasSelectComponent,
FilterSelectComponent, FilterSelectComponent,
TimewindowConfigPanelComponent,
WidgetSettingsComponent WidgetSettingsComponent
] ]
}) })

0
ui-ngx/src/app/modules/home/components/widget/widget-config.component.models.ts → ui-ngx/src/app/modules/home/components/widget/config/widget-config.component.models.ts

45
ui-ngx/src/app/modules/home/components/widget/widget-config.scss → ui-ngx/src/app/modules/home/components/widget/config/widget-config.scss

@ -80,6 +80,30 @@
} }
} }
.mat-mdc-form-field {
&.center {
.mat-mdc-text-field-wrapper.mdc-text-field--outlined {
.mat-mdc-form-field-infix {
.mdc-text-field__input {
text-align: center;
}
}
}
}
&.number {
.mat-mdc-text-field-wrapper.mdc-text-field--outlined {
padding-right: 4px;
.mat-mdc-form-field-infix {
width: 80px;
input.mdc-text-field__input[type=number]::-webkit-inner-spin-button,
input.mdc-text-field__input[type=number]::-webkit-outer-spin-button {
opacity: 1;
}
}
}
}
}
.tb-widget-config-row { .tb-widget-config-row {
.mat-mdc-form-field { .mat-mdc-form-field {
.mat-mdc-text-field-wrapper.mdc-text-field--outlined { .mat-mdc-text-field-wrapper.mdc-text-field--outlined {
@ -97,27 +121,6 @@
width: 72px; width: 72px;
} }
} }
&.center {
.mat-mdc-text-field-wrapper.mdc-text-field--outlined {
.mat-mdc-form-field-infix {
.mdc-text-field__input {
text-align: center;
}
}
}
}
&.number {
.mat-mdc-text-field-wrapper.mdc-text-field--outlined {
padding-right: 4px;
.mat-mdc-form-field-infix {
width: 80px;
input.mdc-text-field__input[type=number]::-webkit-inner-spin-button,
input.mdc-text-field__input[type=number]::-webkit-outer-spin-button {
opacity: 1;
}
}
}
}
} }
} }

0
ui-ngx/src/app/modules/home/components/widget/widget-settings.component.html → ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.html

0
ui-ngx/src/app/modules/home/components/widget/widget-settings.component.scss → ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.scss

25
ui-ngx/src/app/modules/home/components/widget/widget-settings.component.ts → ui-ngx/src/app/modules/home/components/widget/config/widget-settings.component.ts

@ -16,28 +16,27 @@
import { import {
AfterViewInit, AfterViewInit,
Component, ComponentFactoryResolver, Component,
ComponentFactoryResolver,
ComponentRef, ComponentRef,
forwardRef, forwardRef,
Input, OnChanges, Input,
OnChanges,
OnDestroy, OnDestroy,
OnInit, SimpleChanges, OnInit,
SimpleChanges,
ViewChild, ViewChild,
ViewContainerRef ViewContainerRef
} from '@angular/core'; } from '@angular/core';
import { ControlValueAccessor, UntypedFormBuilder, UntypedFormGroup, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { import {
IRuleNodeConfigurationComponent, ControlValueAccessor,
RuleNodeConfiguration, NG_VALUE_ACCESSOR,
RuleNodeDefinition UntypedFormBuilder,
} from '@shared/models/rule-node.models'; UntypedFormGroup,
Validators
} from '@angular/forms';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { RuleChainService } from '@core/http/rule-chain.service';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { JsonObjectEditComponent } from '@shared/components/json-object-edit.component';
import { deepClone } from '@core/utils';
import { RuleChainType } from '@shared/models/rule-chain.models';
import { JsonFormComponent } from '@shared/components/json-form/json-form.component'; import { JsonFormComponent } from '@shared/components/json-form/json-form.component';
import { JsonFormComponentData } from '@shared/components/json-form/json-form-component.models'; import { JsonFormComponentData } from '@shared/components/json-form/json-form-component.models';
import { IWidgetSettingsComponent, Widget, WidgetSettings } from '@shared/models/widget.models'; import { IWidgetSettingsComponent, Widget, WidgetSettings } from '@shared/models/widget.models';

0
ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.html → ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.html

0
ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.scss → ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.scss

0
ui-ngx/src/app/modules/home/components/widget/trip-animation/trip-animation.component.ts → ui-ngx/src/app/modules/home/components/widget/lib/trip-animation/trip-animation.component.ts

31
ui-ngx/src/app/modules/home/components/widget/widget-config.component.html

@ -199,31 +199,12 @@
</div> </div>
</ng-template> </ng-template>
<ng-template #data> <ng-template #data>
<div *ngIf="displayTimewindowConfig" [formGroup]="dataSettings" class="tb-widget-config-panel"> <ng-container *ngIf="displayTimewindowConfig" [formGroup]="dataSettings">
<div fxLayout="row" fxLayoutAlign="space-between center"> <tb-timewindow-config-panel
<div class="tb-widget-config-panel-title" translate>timewindow.timewindow</div> [onlyHistoryTimewindow]="onlyHistoryTimewindow()"
<tb-toggle-header (valueChange)="dataSettings.get('useDashboardTimewindow').patchValue($event)" ignoreMdLgSize="true" formControlName="timewindowConfig">
[options]="[ </tb-timewindow-config-panel>
{ name: translate.instant('widget-config.use-dashboard-timewindow'), value: true}, </ng-container>
{ name: translate.instant('widget-config.use-widget-timewindow'), value: false}
]"
[value]="dataSettings.get('useDashboardTimewindow').value" name="useDashboardTimewindow" useSelectOnMdLg="false">
</tb-toggle-header>
</div>
<div class="tb-widget-config-row">
<tb-timewindow asButton="true"
strokedButton
isEdit="true"
alwaysDisplayTypePrefix
[historyOnly]="onlyHistoryTimewindow()"
quickIntervalOnly="{{ widgetType === widgetTypes.latest }}"
aggregation="{{ widgetType === widgetTypes.timeseries }}"
formControlName="timewindow"></tb-timewindow>
<mat-slide-toggle class="mat-slide" formControlName="displayTimewindow">
{{ 'widget-config.display-timewindow' | translate }}
</mat-slide-toggle>
</div>
</div>
<div *ngIf="widgetType === widgetTypes.alarm" [formGroup]="dataSettings" class="tb-widget-config-panel" fxLayout="column" fxLayoutAlign="center"> <div *ngIf="widgetType === widgetTypes.alarm" [formGroup]="dataSettings" class="tb-widget-config-panel" fxLayout="column" fxLayoutAlign="center">
<tb-alarm-filter-config buttonMode="false" formControlName="alarmFilterConfig"></tb-alarm-filter-config> <tb-alarm-filter-config buttonMode="false" formControlName="alarmFilterConfig"></tb-alarm-filter-config>
</div> </div>

259
ui-ngx/src/app/modules/home/components/widget/widget-config.component.ts

@ -65,7 +65,7 @@ import { Observable, of, Subscription } from 'rxjs';
import { import {
IBasicWidgetConfigComponent, IBasicWidgetConfigComponent,
WidgetConfigCallbacks WidgetConfigCallbacks
} from '@home/components/widget/widget-config.component.models'; } from '@home/components/widget/config/widget-config.component.models';
import { import {
EntityAliasDialogComponent, EntityAliasDialogComponent,
EntityAliasDialogData EntityAliasDialogData
@ -80,8 +80,9 @@ import { Filter, singleEntityFilterFromDeviceId } from '@shared/models/query/que
import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component'; import { FilterDialogComponent, FilterDialogData } from '@home/components/filter/filter-dialog.component';
import { ToggleHeaderOption } from '@shared/components/toggle-header.component'; import { ToggleHeaderOption } from '@shared/components/toggle-header.component';
import { coerceBoolean } from '@shared/decorators/coercion'; import { coerceBoolean } from '@shared/decorators/coercion';
import { basicWidgetConfigComponentsMap } from '@home/components/widget/basic-config/basic-widget-config.module'; import { basicWidgetConfigComponentsMap } from '@home/components/widget/config/basic/basic-widget-config.module';
import Timeout = NodeJS.Timeout; import Timeout = NodeJS.Timeout;
import { TimewindowConfigData } from '@home/components/widget/timewindow-config-panel.component';
const emptySettingsSchema: JsonSchema = { const emptySettingsSchema: JsonSchema = {
type: 'object', type: 'object',
@ -188,6 +189,8 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
private advancedSettingsSubscription: Subscription; private advancedSettingsSubscription: Subscription;
private actionsSettingsSubscription: Subscription; private actionsSettingsSubscription: Subscription;
private defaultConfigFormsType: widgetType;
constructor(protected store: Store<AppState>, constructor(protected store: Store<AppState>,
private utils: UtilsService, private utils: UtilsService,
private entityService: EntityService, private entityService: EntityService,
@ -356,12 +359,11 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
this.targetDeviceSettings = this.fb.group({}); this.targetDeviceSettings = this.fb.group({});
this.advancedSettings = this.fb.group({}); this.advancedSettings = this.fb.group({});
if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) { if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) {
this.dataSettings.addControl('useDashboardTimewindow', this.fb.control(true)); this.dataSettings.addControl('timewindowConfig', this.fb.control({
this.dataSettings.addControl('displayTimewindow', this.fb.control({value: true, disabled: true})); useDashboardTimewindow: true,
this.dataSettings.addControl('timewindow', this.fb.control({value: null, disabled: true})); displayTimewindow: true,
this.dataSettings.get('useDashboardTimewindow').valueChanges.subscribe(() => { timewindow: null
this.updateDataSettingsEnabledState(); }));
});
if (this.widgetType === widgetType.alarm) { if (this.widgetType === widgetType.alarm) {
this.dataSettings.addControl('alarmFilterConfig', this.fb.control(null)); this.dataSettings.addControl('alarmFilterConfig', this.fb.control(null));
} }
@ -396,16 +398,19 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
writeValue(value: WidgetConfigComponentData): void { writeValue(value: WidgetConfigComponentData): void {
this.modelValue = value; this.modelValue = value;
this.widgetType = this.modelValue?.widgetType;
this.setupConfig(); this.setupConfig();
} }
private setupConfig() { private setupConfig() {
this.destroyBasicModeComponent(); if (this.modelValue) {
this.removeChangeSubscriptions(); this.destroyBasicModeComponent();
if (this.hasBasicModeDirective && this.widgetConfigMode === WidgetConfigMode.basic) { this.removeChangeSubscriptions();
this.setupBasicModeConfig(); if (this.hasBasicModeDirective && this.widgetConfigMode === WidgetConfigMode.basic) {
} else { this.setupBasicModeConfig();
this.setupDefaultConfig(); } else {
this.setupDefaultConfig();
}
} }
} }
@ -451,123 +456,116 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
} }
private setupDefaultConfig() { private setupDefaultConfig() {
if (this.modelValue) { if (this.defaultConfigFormsType !== this.widgetType) {
if (this.widgetType !== this.modelValue.widgetType) { this.defaultConfigFormsType = this.widgetType;
this.widgetType = this.modelValue.widgetType; this.buildForms();
this.buildForms(); }
this.buildHeader();
const config = this.modelValue.config;
const layout = this.modelValue.layout;
if (config) {
const displayWidgetTitle = isDefined(config.showTitle) ? config.showTitle : false;
this.widgetSettings.patchValue({
title: config.title,
showTitleIcon: isDefined(config.showTitleIcon) && displayWidgetTitle ? config.showTitleIcon : false,
titleIcon: isDefined(config.titleIcon) ? config.titleIcon : '',
iconColor: isDefined(config.iconColor) ? config.iconColor : 'rgba(0, 0, 0, 0.87)',
iconSize: isDefined(config.iconSize) ? config.iconSize : '24px',
titleTooltip: isDefined(config.titleTooltip) ? config.titleTooltip : '',
showTitle: displayWidgetTitle,
dropShadow: isDefined(config.dropShadow) ? config.dropShadow : true,
enableFullscreen: isDefined(config.enableFullscreen) ? config.enableFullscreen : true,
backgroundColor: config.backgroundColor,
color: config.color,
padding: config.padding,
margin: config.margin,
widgetStyle: isDefined(config.widgetStyle) ? config.widgetStyle : {},
widgetCss: isDefined(config.widgetCss) ? config.widgetCss : '',
titleStyle: isDefined(config.titleStyle) ? config.titleStyle : {
fontSize: '16px',
fontWeight: 400
},
pageSize: isDefined(config.pageSize) ? config.pageSize : 1024,
units: config.units,
decimals: config.decimals,
noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : ''
},
{emitEvent: false}
);
this.updateWidgetSettingsEnabledState();
this.actionsSettings.patchValue(
{
actions: config.actions || {}
},
{emitEvent: false}
);
if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) {
const useDashboardTimewindow = isDefined(config.useDashboardTimewindow) ?
config.useDashboardTimewindow : true;
this.dataSettings.get('timewindowConfig').patchValue({
useDashboardTimewindow,
displayTimewindow: isDefined(config.displayTimewindow) ?
config.displayTimewindow : true,
timewindow: config.timewindow
}, {emitEvent: false});
} }
this.buildHeader(); if (this.modelValue.isDataEnabled) {
const config = this.modelValue.config; if (this.widgetType !== widgetType.rpc &&
const layout = this.modelValue.layout; this.widgetType !== widgetType.alarm &&
if (config) { this.widgetType !== widgetType.static) {
const displayWidgetTitle = isDefined(config.showTitle) ? config.showTitle : false; this.dataSettings.patchValue({ datasources: config.datasources},
this.widgetSettings.patchValue({ {emitEvent: false});
title: config.title, } else if (this.widgetType === widgetType.rpc) {
showTitleIcon: isDefined(config.showTitleIcon) && displayWidgetTitle ? config.showTitleIcon : false, let targetDeviceAliasId: string;
titleIcon: isDefined(config.titleIcon) ? config.titleIcon : '', if (config.targetDeviceAliasIds && config.targetDeviceAliasIds.length > 0) {
iconColor: isDefined(config.iconColor) ? config.iconColor : 'rgba(0, 0, 0, 0.87)', const aliasId = config.targetDeviceAliasIds[0];
iconSize: isDefined(config.iconSize) ? config.iconSize : '24px', const entityAliases = this.aliasController.getEntityAliases();
titleTooltip: isDefined(config.titleTooltip) ? config.titleTooltip : '', if (entityAliases[aliasId]) {
showTitle: displayWidgetTitle, targetDeviceAliasId = entityAliases[aliasId].id;
dropShadow: isDefined(config.dropShadow) ? config.dropShadow : true, } else {
enableFullscreen: isDefined(config.enableFullscreen) ? config.enableFullscreen : true, targetDeviceAliasId = null;
backgroundColor: config.backgroundColor, }
color: config.color, } else {
padding: config.padding, targetDeviceAliasId = null;
margin: config.margin, }
widgetStyle: isDefined(config.widgetStyle) ? config.widgetStyle : {}, this.targetDeviceSettings.patchValue({
widgetCss: isDefined(config.widgetCss) ? config.widgetCss : '', targetDeviceAliasId
titleStyle: isDefined(config.titleStyle) ? config.titleStyle : { }, {emitEvent: false});
fontSize: '16px', } else if (this.widgetType === widgetType.alarm) {
fontWeight: 400 this.dataSettings.patchValue(
}, { alarmFilterConfig: isDefined(config.alarmFilterConfig) ?
pageSize: isDefined(config.pageSize) ? config.pageSize : 1024, config.alarmFilterConfig :
units: config.units, { statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true },
decimals: config.decimals, alarmSource: config.alarmSource }, {emitEvent: false}
noDataDisplayMessage: isDefined(config.noDataDisplayMessage) ? config.noDataDisplayMessage : '' );
}
}
this.updateSchemaForm(config.settings);
if (layout) {
this.layoutSettings.patchValue(
{
mobileOrder: layout.mobileOrder,
mobileHeight: layout.mobileHeight,
mobileHide: layout.mobileHide,
desktopHide: layout.desktopHide
}, },
{emitEvent: false} {emitEvent: false}
); );
this.updateWidgetSettingsEnabledState(); } else {
this.actionsSettings.patchValue( this.layoutSettings.patchValue(
{ {
actions: config.actions || {} mobileOrder: null,
mobileHeight: null,
mobileHide: false,
desktopHide: false
}, },
{emitEvent: false} {emitEvent: false}
); );
if (this.widgetType === widgetType.timeseries || this.widgetType === widgetType.alarm || this.widgetType === widgetType.latest) {
const useDashboardTimewindow = isDefined(config.useDashboardTimewindow) ?
config.useDashboardTimewindow : true;
this.dataSettings.patchValue(
{ useDashboardTimewindow }, {emitEvent: false}
);
this.dataSettings.patchValue(
{ displayTimewindow: isDefined(config.displayTimewindow) ?
config.displayTimewindow : true }, {emitEvent: false}
);
this.dataSettings.patchValue(
{ timewindow: config.timewindow }, {emitEvent: false}
);
this.updateDataSettingsEnabledState();
}
if (this.modelValue.isDataEnabled) {
if (this.widgetType !== widgetType.rpc &&
this.widgetType !== widgetType.alarm &&
this.widgetType !== widgetType.static) {
this.dataSettings.patchValue({ datasources: config.datasources},
{emitEvent: false});
} else if (this.widgetType === widgetType.rpc) {
let targetDeviceAliasId: string;
if (config.targetDeviceAliasIds && config.targetDeviceAliasIds.length > 0) {
const aliasId = config.targetDeviceAliasIds[0];
const entityAliases = this.aliasController.getEntityAliases();
if (entityAliases[aliasId]) {
targetDeviceAliasId = entityAliases[aliasId].id;
} else {
targetDeviceAliasId = null;
}
} else {
targetDeviceAliasId = null;
}
this.targetDeviceSettings.patchValue({
targetDeviceAliasId
}, {emitEvent: false});
} else if (this.widgetType === widgetType.alarm) {
this.dataSettings.patchValue(
{ alarmFilterConfig: isDefined(config.alarmFilterConfig) ?
config.alarmFilterConfig :
{ statusList: [AlarmSearchStatus.ACTIVE], searchPropagatedAlarms: true },
alarmSource: config.alarmSource }, {emitEvent: false}
);
}
}
this.updateSchemaForm(config.settings);
if (layout) {
this.layoutSettings.patchValue(
{
mobileOrder: layout.mobileOrder,
mobileHeight: layout.mobileHeight,
mobileHide: layout.mobileHide,
desktopHide: layout.desktopHide
},
{emitEvent: false}
);
} else {
this.layoutSettings.patchValue(
{
mobileOrder: null,
mobileHeight: null,
mobileHide: false,
desktopHide: false
},
{emitEvent: false}
);
}
} }
this.createChangeSubscriptions();
} }
this.createChangeSubscriptions();
} }
private updateWidgetSettingsEnabledState() { private updateWidgetSettingsEnabledState() {
@ -595,17 +593,6 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
} }
} }
private updateDataSettingsEnabledState() {
const useDashboardTimewindow: boolean = this.dataSettings.get('useDashboardTimewindow').value;
if (useDashboardTimewindow) {
this.dataSettings.get('displayTimewindow').disable({emitEvent: false});
this.dataSettings.get('timewindow').disable({emitEvent: false});
} else {
this.dataSettings.get('displayTimewindow').enable({emitEvent: false});
this.dataSettings.get('timewindow').enable({emitEvent: false});
}
}
private updateSchemaForm(settings?: any) { private updateSchemaForm(settings?: any) {
const widgetSettingsFormData: JsonFormComponentData = {}; const widgetSettingsFormData: JsonFormComponentData = {};
if (this.modelValue.settingsSchema && this.modelValue.settingsSchema.schema) { if (this.modelValue.settingsSchema && this.modelValue.settingsSchema.schema) {
@ -626,7 +613,13 @@ export class WidgetConfigComponent extends PageComponent implements OnInit, OnDe
private updateDataSettings() { private updateDataSettings() {
if (this.modelValue) { if (this.modelValue) {
if (this.modelValue.config) { if (this.modelValue.config) {
Object.assign(this.modelValue.config, this.dataSettings.value); let data = this.dataSettings.value;
if (data.timewindowConfig) {
const timewindowConfig: TimewindowConfigData = data.timewindowConfig;
data = {...data, ...timewindowConfig};
delete data.timewindowConfig;
}
Object.assign(this.modelValue.config, data);
} }
this.propagateChange(this.modelValue); this.propagateChange(this.modelValue);
} }

Loading…
Cancel
Save