UI: Improve data keys config. Fix datasource type processing.
This commit is contained in:
parent
6b8cbbd3c9
commit
1ec37d7685
@ -252,10 +252,9 @@ export class AliasController implements IAliasController {
|
||||
|
||||
private resolveDatasource(datasource: Datasource, forceFilter = false): Observable<Datasource> {
|
||||
const newDatasource = deepClone(datasource);
|
||||
if (newDatasource.type === DatasourceType.device) {
|
||||
newDatasource.type = DatasourceType.entity;
|
||||
}
|
||||
if (newDatasource.type === DatasourceType.entity || newDatasource.type === DatasourceType.entityCount
|
||||
if (newDatasource.type === DatasourceType.entity
|
||||
|| newDatasource.type === DatasourceType.device
|
||||
|| newDatasource.type === DatasourceType.entityCount
|
||||
|| newDatasource.type === DatasourceType.alarmCount) {
|
||||
if (newDatasource.filterId) {
|
||||
newDatasource.keyFilters = this.getKeyFilters(newDatasource.filterId);
|
||||
@ -263,7 +262,8 @@ export class AliasController implements IAliasController {
|
||||
if (newDatasource.type === DatasourceType.alarmCount) {
|
||||
newDatasource.alarmFilter = this.entityService.resolveAlarmFilter(newDatasource.alarmFilterConfig, false);
|
||||
}
|
||||
if (newDatasource.deviceId) {
|
||||
if (newDatasource.type === DatasourceType.device) {
|
||||
newDatasource.type = DatasourceType.entity;
|
||||
newDatasource.entityFilter = singleEntityFilterFromDeviceId(newDatasource.deviceId);
|
||||
if (forceFilter) {
|
||||
return this.entityService.findSingleEntityInfoByEntityFilter(newDatasource.entityFilter,
|
||||
|
||||
@ -282,13 +282,9 @@ export class UtilsService {
|
||||
|
||||
public validateDatasources(datasources: Array<Datasource>): Array<Datasource> {
|
||||
datasources.forEach((datasource) => {
|
||||
// @ts-ignore
|
||||
if (datasource.type === 'device') {
|
||||
if (datasource.type === DatasourceType.device) {
|
||||
if (datasource.deviceAliasId) {
|
||||
datasource.type = DatasourceType.entity;
|
||||
datasource.entityType = EntityType.DEVICE;
|
||||
if (datasource.deviceId) {
|
||||
datasource.entityId = datasource.deviceId;
|
||||
} else if (datasource.deviceAliasId) {
|
||||
datasource.entityAliasId = datasource.deviceAliasId;
|
||||
}
|
||||
if (datasource.deviceName) {
|
||||
|
||||
@ -97,8 +97,10 @@ export abstract class WebsocketService<T extends WsSubscriber> implements WsServ
|
||||
this.dataStream.next(this.cmdWrapper.preparePublishCommands(MAX_PUBLISH_COMMANDS));
|
||||
this.checkToClose();
|
||||
}
|
||||
if (this.subscribersCount > 0) {
|
||||
this.tryOpenSocket();
|
||||
}
|
||||
}
|
||||
|
||||
private checkToClose() {
|
||||
if (this.subscribersCount === 0 && this.isOpened) {
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
<tb-data-keys-panel
|
||||
panelTitle="{{ 'widgets.table.columns' | translate }}"
|
||||
addKeyTitle="{{ 'widgets.table.add-column' | translate }}"
|
||||
keySettingsTitle="{{ 'widgets.table.column-settings' | translate }}"
|
||||
removeKeyTitle="{{ 'widgets.table.remove-column' | translate }}"
|
||||
noKeysText="{{ 'widgets.table.no-columns' | translate }}"
|
||||
hideDataKeyColor
|
||||
|
||||
@ -151,6 +151,22 @@
|
||||
<input matInput formControlName="decimals" type="number" min="0" max="15" step="1" placeholder="{{ 'widget-config.set' | translate }}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="tb-data-keys-table-row-buttons">
|
||||
<button type="button"
|
||||
mat-icon-button
|
||||
(click)="editKey(true)"
|
||||
[matTooltip]="keySettingsTitle"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
<button type="button"
|
||||
mat-icon-button
|
||||
(click)="keyRemoved.emit()"
|
||||
[matTooltip]="removeKeyTitle"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #keyName>
|
||||
<ng-container *ngIf="dataKeyHasPostprocessing(); else keyName">
|
||||
|
||||
@ -51,3 +51,19 @@
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.tb-data-keys-table-row-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
button.mat-mdc-icon-button.mat-mdc-button-base {
|
||||
padding: 7px;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
.mat-icon {
|
||||
color: rgba(0, 0, 0, 0.38);
|
||||
}
|
||||
&.tb-hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,10 +18,12 @@ import {
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
forwardRef,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewChild,
|
||||
ViewEncapsulation
|
||||
@ -37,7 +39,14 @@ import {
|
||||
} from '@angular/forms';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { WidgetConfigComponent } from '@home/components/widget/widget-config.component';
|
||||
import { DataKey, DatasourceType, JsonSettingsSchema, Widget, widgetType } from '@shared/models/widget.models';
|
||||
import {
|
||||
DataKey,
|
||||
DataKeyConfigMode,
|
||||
DatasourceType,
|
||||
JsonSettingsSchema,
|
||||
Widget,
|
||||
widgetType
|
||||
} from '@shared/models/widget.models';
|
||||
import { DataKeysPanelComponent } from '@home/components/widget/config/basic/common/data-keys-panel.component';
|
||||
import { DataKeyType } from '@shared/models/telemetry/telemetry.models';
|
||||
import { AggregationType } from '@shared/models/time/time.models';
|
||||
@ -104,6 +113,9 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan
|
||||
@Input()
|
||||
deviceId: string;
|
||||
|
||||
@Output()
|
||||
keyRemoved = new EventEmitter();
|
||||
|
||||
keyFormControl: UntypedFormControl;
|
||||
|
||||
keyRowFormGroup: UntypedFormGroup;
|
||||
@ -169,6 +181,18 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan
|
||||
return this.modelValue.type && ![ DataKeyType.alarm, DataKeyType.entityField, DataKeyType.count ].includes(this.modelValue.type);
|
||||
}
|
||||
|
||||
get keySettingsTitle(): string {
|
||||
return this.dataKeysPanelComponent.keySettingsTitle;
|
||||
}
|
||||
|
||||
get removeKeyTitle(): string {
|
||||
return this.dataKeysPanelComponent.removeKeyTitle;
|
||||
}
|
||||
|
||||
get dragEnabled(): boolean {
|
||||
return this.dataKeysPanelComponent.dragEnabled;
|
||||
}
|
||||
|
||||
private propagateChange = (_val: any) => {};
|
||||
|
||||
constructor(private fb: UntypedFormBuilder,
|
||||
@ -291,13 +315,14 @@ export class DataKeyRowComponent implements ControlValueAccessor, OnInit, OnChan
|
||||
}
|
||||
}
|
||||
|
||||
editKey() {
|
||||
editKey(advanced = false) {
|
||||
this.dialog.open<DataKeyConfigDialogComponent, DataKeyConfigDialogData, DataKey>(DataKeyConfigDialogComponent,
|
||||
{
|
||||
disableClose: true,
|
||||
panelClass: ['tb-dialog', 'tb-fullscreen-dialog'],
|
||||
data: {
|
||||
dataKey: deepClone(this.modelValue),
|
||||
dataKeyConfigMode: advanced ? DataKeyConfigMode.advanced : DataKeyConfigMode.general,
|
||||
dataKeySettingsSchema: this.datakeySettingsSchema,
|
||||
dataKeySettingsDirective: this.dataKeySettingsDirective,
|
||||
dashboard: this.dashboard,
|
||||
|
||||
@ -26,27 +26,25 @@
|
||||
<div class="tb-data-keys-header-cell tb-decimals-header" translate>widget-config.decimals-short</div>
|
||||
<div class="tb-data-keys-header-cell tb-actions-header"></div>
|
||||
</div>
|
||||
<div *ngIf="keysFormArray().controls.length; else noKeys" class="tb-data-keys-body tb-drop-list" cdkDropList cdkDropListOrientation="vertical"
|
||||
<div *ngIf="keysFormArray().controls.length; else noKeys" class="tb-data-keys-body tb-drop-list"
|
||||
cdkDropList cdkDropListOrientation="vertical"
|
||||
[cdkDropListDisabled]="!dragEnabled"
|
||||
(cdkDropListDropped)="keyDrop($event)">
|
||||
<div cdkDrag class="tb-data-keys-table-row tb-draggable" *ngFor="let keyControl of keysFormArray().controls; trackBy: trackByKey;
|
||||
let $index = index;">
|
||||
<div cdkDrag [cdkDragDisabled]="!dragEnabled"
|
||||
class="tb-data-keys-table-row tb-draggable"
|
||||
*ngFor="let keyControl of keysFormArray().controls; trackBy: trackByKey; let $index = index;">
|
||||
<tb-data-key-row fxFlex
|
||||
[formControl]="keyControl"
|
||||
[datasourceType]="datasourceType"
|
||||
[deviceId]="deviceId"
|
||||
[entityAliasId]="entityAliasId">
|
||||
[entityAliasId]="entityAliasId"
|
||||
(keyRemoved)="removeKey($index)">
|
||||
</tb-data-key-row>
|
||||
<div class="tb-data-keys-table-row-buttons">
|
||||
<button type="button"
|
||||
mat-icon-button
|
||||
(click)="removeKey($index)"
|
||||
[matTooltip]="removeKeyTitle"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button
|
||||
type="button"
|
||||
cdkDragHandle
|
||||
[ngClass]="{'tb-hidden': !dragEnabled}"
|
||||
matTooltip="{{ 'action.drag' | translate }}"
|
||||
matTooltipPosition="above">
|
||||
<mat-icon>drag_indicator</mat-icon>
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
width: 60px;
|
||||
}
|
||||
&.tb-actions-header {
|
||||
width: 76px;
|
||||
width: 114px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,20 +57,5 @@
|
||||
height: 38px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 12px;
|
||||
background: #fff;
|
||||
|
||||
.tb-data-keys-table-row-buttons {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
button.mat-mdc-icon-button.mat-mdc-button-base {
|
||||
padding: 7px;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
.mat-icon {
|
||||
color: rgba(0, 0, 0, 0.38);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -75,6 +75,9 @@ export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnC
|
||||
@Input()
|
||||
addKeyTitle: string;
|
||||
|
||||
@Input()
|
||||
keySettingsTitle: string;
|
||||
|
||||
@Input()
|
||||
removeKeyTitle: string;
|
||||
|
||||
@ -112,6 +115,10 @@ export class DataKeysPanelComponent implements ControlValueAccessor, OnInit, OnC
|
||||
return this.widgetConfigComponent.modelValue?.dataKeySettingsSchema;
|
||||
}
|
||||
|
||||
get dragEnabled(): boolean {
|
||||
return this.keysFormArray().controls.length > 1;
|
||||
}
|
||||
|
||||
private propagateChange = (_val: any) => {};
|
||||
|
||||
constructor(private fb: UntypedFormBuilder,
|
||||
|
||||
@ -19,6 +19,10 @@
|
||||
<mat-toolbar color="primary">
|
||||
<h2>{{ 'datakey.configuration' | translate }}</h2>
|
||||
<span fxFlex></span>
|
||||
<tb-toggle-header *ngIf="hasAdvanced" (valueChange)="dataKeyConfigMode = $event" ignoreMdLgSize="true"
|
||||
appearance="fill-invert" [options]="dataKeyConfigHeaderOptions"
|
||||
[value]="dataKeyConfigMode" name="dataKeyConfigModeHeader" useSelectOnMdLg="false">
|
||||
</tb-toggle-header>
|
||||
<button mat-icon-button
|
||||
(click)="cancel()"
|
||||
type="button">
|
||||
@ -28,8 +32,9 @@
|
||||
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async">
|
||||
</mat-progress-bar>
|
||||
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div>
|
||||
<div mat-dialog-content>
|
||||
<div mat-dialog-content style="padding: 0; height: 800px; overflow: auto;">
|
||||
<tb-data-key-config #dataKeyConfig
|
||||
[dataKeyConfigMode]="dataKeyConfigMode"
|
||||
[dataKeySettingsSchema]="data.dataKeySettingsSchema"
|
||||
[dataKeySettingsDirective]="data.dataKeySettingsDirective"
|
||||
[deviceId]="data.deviceId"
|
||||
|
||||
@ -19,17 +19,27 @@ import { ErrorStateMatcher } from '@angular/material/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AppState } from '@core/core.state';
|
||||
import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
|
||||
import {
|
||||
FormGroupDirective,
|
||||
NgForm,
|
||||
UntypedFormBuilder,
|
||||
UntypedFormControl,
|
||||
UntypedFormGroup,
|
||||
Validators
|
||||
} from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { DialogComponent } from '@shared/components/dialog.component';
|
||||
import { DataKey, Widget, widgetType } from '@shared/models/widget.models';
|
||||
import { DataKey, DataKeyConfigMode, Widget, widgetType } from '@shared/models/widget.models';
|
||||
import { DataKeysCallbacks } from './data-keys.component.models';
|
||||
import { DataKeyConfigComponent } from '@home/components/widget/config/data-key-config.component';
|
||||
import { Dashboard } from '@shared/models/dashboard.models';
|
||||
import { IAliasController } from '@core/api/widget-api.models';
|
||||
import { ToggleHeaderOption } from '@shared/components/toggle-header.component';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
export interface DataKeyConfigDialogData {
|
||||
dataKey: DataKey;
|
||||
dataKeyConfigMode?: DataKeyConfigMode;
|
||||
dataKeySettingsSchema: any;
|
||||
dataKeySettingsDirective: string;
|
||||
dashboard: Dashboard;
|
||||
@ -57,6 +67,12 @@ export class DataKeyConfigDialogComponent extends DialogComponent<DataKeyConfigD
|
||||
|
||||
@ViewChild('dataKeyConfig', {static: true}) dataKeyConfig: DataKeyConfigComponent;
|
||||
|
||||
hasAdvanced = false;
|
||||
|
||||
dataKeyConfigHeaderOptions: ToggleHeaderOption[];
|
||||
|
||||
dataKeyConfigMode: DataKeyConfigMode = DataKeyConfigMode.general;
|
||||
|
||||
dataKeyFormGroup: UntypedFormGroup;
|
||||
|
||||
submitted = false;
|
||||
@ -66,6 +82,7 @@ export class DataKeyConfigDialogComponent extends DialogComponent<DataKeyConfigD
|
||||
@Inject(MAT_DIALOG_DATA) public data: DataKeyConfigDialogData,
|
||||
@SkipSelf() private errorStateMatcher: ErrorStateMatcher,
|
||||
public dialogRef: MatDialogRef<DataKeyConfigDialogComponent, DataKey>,
|
||||
private translate: TranslateService,
|
||||
public fb: UntypedFormBuilder) {
|
||||
super(store, router, dialogRef);
|
||||
}
|
||||
@ -74,6 +91,23 @@ export class DataKeyConfigDialogComponent extends DialogComponent<DataKeyConfigD
|
||||
this.dataKeyFormGroup = this.fb.group({
|
||||
dataKey: [this.data.dataKey, [Validators.required]]
|
||||
});
|
||||
if (this.data.dataKeySettingsSchema && this.data.dataKeySettingsSchema.schema ||
|
||||
this.data.dataKeySettingsDirective && this.data.dataKeySettingsDirective.length) {
|
||||
this.hasAdvanced = true;
|
||||
this.dataKeyConfigHeaderOptions = [
|
||||
{
|
||||
name: this.translate.instant('datakey.general'),
|
||||
value: DataKeyConfigMode.general
|
||||
},
|
||||
{
|
||||
name: this.translate.instant('datakey.advanced'),
|
||||
value: DataKeyConfigMode.advanced
|
||||
}
|
||||
];
|
||||
if (this.data.dataKeyConfigMode) {
|
||||
this.dataKeyConfigMode = this.data.dataKeyConfigMode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean {
|
||||
|
||||
@ -15,10 +15,12 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<mat-tab-group class="tb-datakey-config" [ngClass]="{'tb-headless': !displayAdvanced}">
|
||||
<mat-tab [formGroup]="dataKeyFormGroup" label="{{ 'datakey.settings' | translate }}">
|
||||
<div class="mat-padding settings" fxLayout="column">
|
||||
<mat-form-field class="mat-block" *ngIf="modelValue.type !== dataKeyTypes.function">
|
||||
<div class="tb-datakey-config" *ngIf="dataKeyConfigMode === dataKeyConfigModes.general; else advanced"
|
||||
[formGroup]="dataKeyFormGroup">
|
||||
<div class="mat-padding" fxLayout="column" style="gap: 16px;">
|
||||
<div class="tb-widget-config-panel">
|
||||
<div class="tb-widget-config-panel-title" translate>datakey.general</div>
|
||||
<mat-form-field *ngIf="modelValue.type !== dataKeyTypes.function" subscriptSizing="dynamic">
|
||||
<mat-label>{{ 'entity.key' | translate }}</mat-label>
|
||||
<input matInput type="text" placeholder="{{ 'entity.key-name' | translate }}"
|
||||
#keyInput
|
||||
@ -39,31 +41,35 @@
|
||||
</mat-option>
|
||||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
<div fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px">
|
||||
<mat-form-field *ngIf="!hideDataKeyLabel" fxFlex class="mat-block">
|
||||
<mat-form-field *ngIf="!hideDataKeyLabel" subscriptSizing="dynamic">
|
||||
<mat-label translate>datakey.label</mat-label>
|
||||
<input matInput formControlName="label" required>
|
||||
</mat-form-field>
|
||||
<tb-color-input *ngIf="!hideDataKeyColor" fxFlex
|
||||
required
|
||||
label="{{'datakey.color' | translate}}"
|
||||
icon="format_color_fill"
|
||||
openOnInput
|
||||
<ng-container *ngIf="modelValue.type !== dataKeyTypes.alarm">
|
||||
<div class="tb-widget-config-row space-between" *ngIf="!hideDataKeyUnits">
|
||||
<div translate>widget-config.units-short</div>
|
||||
<tb-widget-units
|
||||
formControlName="units">
|
||||
</tb-widget-units>
|
||||
</div>
|
||||
<div class="tb-widget-config-row space-between" *ngIf="!hideDataKeyDecimals">
|
||||
<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>
|
||||
</ng-container>
|
||||
<div class="tb-widget-config-row space-between same-padding" *ngIf="!hideDataKeyColor">
|
||||
<div>{{ 'datakey.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 fxLayout="row" fxLayout.xs="column" fxLayoutAlign="start center" fxLayoutAlign.xs fxLayoutGap="8px" *ngIf="modelValue.type !== dataKeyTypes.alarm">
|
||||
<mat-form-field *ngIf="!hideDataKeyUnits" fxFlex>
|
||||
<mat-label translate>datakey.units</mat-label>
|
||||
<input matInput formControlName="units">
|
||||
</mat-form-field>
|
||||
<mat-form-field *ngIf="!hideDataKeyDecimals" fxFlex>
|
||||
<mat-label translate>datakey.decimals</mat-label>
|
||||
<input matInput formControlName="decimals" type="number" min="0" max="15" step="1">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<section *ngIf="widgetType === widgetTypes.latest && modelValue.type === dataKeyTypes.timeseries" fxLayout="column">
|
||||
<mat-form-field>
|
||||
<ng-container *ngIf="widgetType === widgetTypes.latest && modelValue.type === dataKeyTypes.timeseries">
|
||||
<mat-form-field subscriptSizing="dynamic">
|
||||
<mat-label translate>datakey.aggregation</mat-label>
|
||||
<mat-select formControlName="aggregationType" style="min-width: 150px;">
|
||||
<mat-option *ngFor="let aggregation of aggregations" [value]="aggregation">
|
||||
@ -80,7 +86,7 @@
|
||||
<fieldset *ngIf="dataKeyFormGroup.get('aggregationType').value && dataKeyFormGroup.get('aggregationType').value !== aggregationTypes.NONE" class="fields-group fields-group-slider">
|
||||
<legend class="group-title" translate>datakey.delta-calculation</legend>
|
||||
<mat-expansion-panel class="tb-settings comparison" [expanded]="dataKeyFormGroup.get('comparisonEnabled').value" [disabled]="!dataKeyFormGroup.get('comparisonEnabled').value">
|
||||
<mat-expansion-panel-header fxLayout="row wrap">
|
||||
<mat-expansion-panel-header fxLayout="row wrap" class="fill-width">
|
||||
<mat-panel-title fxLayout="column" fxLayoutAlign="center start">
|
||||
<mat-slide-toggle formControlName="comparisonEnabled" (click)="$event.stopPropagation()">
|
||||
{{ 'datakey.enable-delta-calculation' | translate }}
|
||||
@ -129,7 +135,7 @@
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
</fieldset>
|
||||
</section>
|
||||
</ng-container>
|
||||
<section fxLayout="column" *ngIf="modelValue.type === dataKeyTypes.function">
|
||||
<span translate>datakey.data-generation-func</span>
|
||||
<br/>
|
||||
@ -142,10 +148,19 @@
|
||||
formControlName="funcBody">
|
||||
</tb-js-func>
|
||||
</section>
|
||||
<section fxLayout="column" *ngIf="(modelValue.type === dataKeyTypes.timeseries || modelValue.type === dataKeyTypes.attribute || modelValue.type === dataKeyTypes.count) && showPostProcessing">
|
||||
<mat-checkbox formControlName="usePostProcessing">
|
||||
</div>
|
||||
<div class="tb-widget-config-panel tb-slide-toggle"
|
||||
*ngIf="(modelValue.type === dataKeyTypes.timeseries || modelValue.type === dataKeyTypes.attribute || modelValue.type === dataKeyTypes.count) && showPostProcessing">
|
||||
<mat-expansion-panel class="tb-settings" [expanded]="dataKeyFormGroup.get('usePostProcessing').value" [disabled]="!dataKeyFormGroup.get('usePostProcessing').value">
|
||||
<mat-expansion-panel-header fxLayout="row wrap">
|
||||
<mat-panel-title>
|
||||
<mat-slide-toggle class="mat-slide" formControlName="usePostProcessing" (click)="$event.stopPropagation()"
|
||||
fxLayoutAlign="center">
|
||||
{{ 'datakey.use-data-post-processing-func' | translate }}
|
||||
</mat-checkbox>
|
||||
</mat-slide-toggle>
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<ng-template matExpansionPanelContent>
|
||||
<tb-js-func *ngIf="dataKeyFormGroup.get('usePostProcessing').value" #postFuncBodyEdit
|
||||
[functionArgs]="['time', 'value', 'prevValue', 'timePrev', 'prevOrigValue']"
|
||||
[globalVariables]="functionScopeVariables"
|
||||
@ -161,10 +176,13 @@
|
||||
timePrev - {{ 'datakey.time-prev-description' | translate }}<br/>
|
||||
prevOrigValue - {{ 'datakey.prev-orig-value-description' | translate }}
|
||||
</label>
|
||||
</section>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
</div>
|
||||
</mat-tab>
|
||||
<mat-tab [formGroup]="dataKeySettingsFormGroup" label="{{ 'datakey.advanced' | translate }}" *ngIf="displayAdvanced">
|
||||
</div>
|
||||
</div>
|
||||
<ng-template #advanced>
|
||||
<div class="tb-datakey-config" [formGroup]="dataKeySettingsFormGroup">
|
||||
<div class="mat-padding" fxLayout="column">
|
||||
<tb-widget-settings
|
||||
[dashboard]="dashboard"
|
||||
@ -173,5 +191,5 @@
|
||||
formControlName="settings">
|
||||
</tb-widget-settings>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@ -17,18 +17,6 @@
|
||||
|
||||
:host {
|
||||
.tb-datakey-config {
|
||||
height: 100%;
|
||||
|
||||
.settings{
|
||||
&> :first-child{
|
||||
padding-top: 12px;
|
||||
}
|
||||
&> :nth-child(n){
|
||||
padding-right: 12px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.fields-group {
|
||||
padding: 0 16px 8px;
|
||||
margin-bottom: 10px;
|
||||
@ -60,7 +48,7 @@
|
||||
}
|
||||
|
||||
.tb-hint.after-fields {
|
||||
margin-top: -1.25em;
|
||||
margin-top: -0.75em;
|
||||
max-width: fit-content;
|
||||
line-height: 15px;
|
||||
}
|
||||
@ -69,15 +57,6 @@
|
||||
|
||||
:host ::ng-deep {
|
||||
.tb-datakey-config {
|
||||
.mat-mdc-tab-body.mat-mdc-tab-body-active {
|
||||
.mat-mdc-tab-body-content > div {
|
||||
height: calc(65vh - 50px);
|
||||
overflow: initial;
|
||||
@media #{$mat-xs} {
|
||||
height: 500px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.mat-expansion-panel {
|
||||
&.tb-settings {
|
||||
box-shadow: none;
|
||||
|
||||
@ -22,7 +22,7 @@ import {
|
||||
ComparisonResultType,
|
||||
comparisonResultTypeTranslationMap,
|
||||
DataKey,
|
||||
dataKeyAggregationTypeHintTranslationMap,
|
||||
dataKeyAggregationTypeHintTranslationMap, DataKeyConfigMode,
|
||||
Widget,
|
||||
widgetType
|
||||
} from '@shared/models/widget.models';
|
||||
@ -73,6 +73,8 @@ import { coerceBoolean } from '@shared/decorators/coercion';
|
||||
})
|
||||
export class DataKeyConfigComponent extends PageComponent implements OnInit, ControlValueAccessor, Validator {
|
||||
|
||||
dataKeyConfigModes = DataKeyConfigMode;
|
||||
|
||||
dataKeyTypes = DataKeyType;
|
||||
|
||||
widgetTypes = widgetType;
|
||||
@ -91,6 +93,9 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con
|
||||
|
||||
comparisonResultTypeTranslations = comparisonResultTypeTranslationMap;
|
||||
|
||||
@Input()
|
||||
dataKeyConfigMode: DataKeyConfigMode;
|
||||
|
||||
@Input()
|
||||
deviceId: string;
|
||||
|
||||
@ -142,7 +147,7 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con
|
||||
@ViewChild('funcBodyEdit') funcBodyEdit: JsFuncComponent;
|
||||
@ViewChild('postFuncBodyEdit') postFuncBodyEdit: JsFuncComponent;
|
||||
|
||||
displayAdvanced = false;
|
||||
hasAdvanced = false;
|
||||
|
||||
modelValue: DataKey;
|
||||
|
||||
@ -193,7 +198,7 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con
|
||||
}
|
||||
if (this.dataKeySettingsSchema && this.dataKeySettingsSchema.schema ||
|
||||
this.dataKeySettingsDirective && this.dataKeySettingsDirective.length) {
|
||||
this.displayAdvanced = true;
|
||||
this.hasAdvanced = true;
|
||||
this.dataKeySettingsData = {
|
||||
schema: this.dataKeySettingsSchema?.schema || {
|
||||
type: 'object',
|
||||
@ -291,7 +296,7 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con
|
||||
}
|
||||
this.dataKeyFormGroup.patchValue(this.modelValue, {emitEvent: false});
|
||||
this.updateValidators();
|
||||
if (this.displayAdvanced) {
|
||||
if (this.hasAdvanced) {
|
||||
this.dataKeySettingsData.model = this.modelValue.settings;
|
||||
this.dataKeySettingsFormGroup.patchValue({
|
||||
settings: this.dataKeySettingsData
|
||||
@ -370,7 +375,7 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con
|
||||
|
||||
private updateModel() {
|
||||
this.modelValue = {...this.modelValue, ...this.dataKeyFormGroup.value};
|
||||
if (this.displayAdvanced) {
|
||||
if (this.hasAdvanced) {
|
||||
this.modelValue.settings = this.dataKeySettingsFormGroup.get('settings').value.model;
|
||||
}
|
||||
if (this.modelValue.name) {
|
||||
@ -449,7 +454,7 @@ export class DataKeyConfigComponent extends PageComponent implements OnInit, Con
|
||||
}
|
||||
};
|
||||
}
|
||||
if (this.displayAdvanced && (!this.dataKeySettingsFormGroup.valid || !this.modelValue.settings)) {
|
||||
if (this.hasAdvanced && (!this.dataKeySettingsFormGroup.valid || !this.modelValue.settings)) {
|
||||
return {
|
||||
dataKeySettings: {
|
||||
valid: false
|
||||
|
||||
@ -15,21 +15,56 @@
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<section class="tb-widget-settings" [formGroup]="entitiesTableKeySettingsForm" fxLayout="column">
|
||||
<mat-form-field fxFlex class="mat-block">
|
||||
<mat-label translate>widgets.table.custom-title</mat-label>
|
||||
<input matInput formControlName="customTitle">
|
||||
<ng-container [formGroup]="entitiesTableKeySettingsForm">
|
||||
<div class="tb-widget-config-panel">
|
||||
<div class="tb-widget-config-panel-title" translate>widgets.table.column-settings</div>
|
||||
<div class="tb-widget-config-row">
|
||||
<div>{{ 'widgets.table.custom-title' | translate }}</div>
|
||||
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic">
|
||||
<input matInput formControlName="customTitle" placeholder="{{ 'widget-config.set' | translate }}">
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex class="mat-block">
|
||||
<mat-label translate>widgets.table.column-width</mat-label>
|
||||
<input matInput formControlName="columnWidth">
|
||||
</div>
|
||||
<div class="tb-widget-config-row space-between">
|
||||
<div>{{ 'widgets.table.column-width' | translate }}</div>
|
||||
<mat-form-field appearance="outline" class="center" subscriptSizing="dynamic">
|
||||
<input matInput formControlName="columnWidth" placeholder="{{ 'widget-config.set' | translate }}">
|
||||
</mat-form-field>
|
||||
<fieldset class="fields-group fields-group-slider">
|
||||
<legend class="group-title" translate>widgets.table.cell-style</legend>
|
||||
</div>
|
||||
<div class="tb-widget-config-row space-between">
|
||||
<div>{{ 'widgets.table.default-column-visibility' | translate }}</div>
|
||||
<mat-form-field style="width: 220px;" appearance="outline" subscriptSizing="dynamic">
|
||||
<mat-select formControlName="defaultColumnVisibility">
|
||||
<mat-option [value]="'visible'">
|
||||
{{ 'widgets.table.column-visibility-visible' | translate }}
|
||||
</mat-option>
|
||||
<mat-option [value]="'hidden'">
|
||||
{{ 'widgets.table.column-visibility-hidden' | translate }}
|
||||
</mat-option>
|
||||
<mat-option [value]="'hidden-mobile'">
|
||||
{{ 'widgets.table.column-visibility-hidden-mobile' | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div class="tb-widget-config-row space-between">
|
||||
<div>{{ 'widgets.table.column-selection-to-display' | translate }}</div>
|
||||
<mat-form-field style="width: 220px;" appearance="outline" subscriptSizing="dynamic">
|
||||
<mat-select formControlName="columnSelectionToDisplay">
|
||||
<mat-option [value]="'enabled'">
|
||||
{{ 'widgets.table.column-selection-to-display-enabled' | translate }}
|
||||
</mat-option>
|
||||
<mat-option [value]="'disabled'">
|
||||
{{ 'widgets.table.column-selection-to-display-disabled' | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tb-widget-config-panel tb-slide-toggle">
|
||||
<mat-expansion-panel class="tb-settings" [expanded]="entitiesTableKeySettingsForm.get('useCellStyleFunction').value">
|
||||
<mat-expansion-panel-header fxLayout="row wrap">
|
||||
<mat-expansion-panel-header fxLayout="row wrap" class="fill-width">
|
||||
<mat-panel-title fxFlex="60">
|
||||
<mat-slide-toggle formControlName="useCellStyleFunction" (click)="$event.stopPropagation()"
|
||||
<mat-slide-toggle class="mat-slide" formControlName="useCellStyleFunction" (click)="$event.stopPropagation()"
|
||||
fxLayoutAlign="center">
|
||||
{{ 'widgets.table.use-cell-style-function' | translate }}
|
||||
</mat-slide-toggle>
|
||||
@ -48,13 +83,12 @@
|
||||
</tb-js-func>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
</fieldset>
|
||||
<fieldset class="fields-group fields-group-slider">
|
||||
<legend class="group-title" translate>widgets.table.cell-content</legend>
|
||||
</div>
|
||||
<div class="tb-widget-config-panel tb-slide-toggle">
|
||||
<mat-expansion-panel class="tb-settings" [expanded]="entitiesTableKeySettingsForm.get('useCellContentFunction').value">
|
||||
<mat-expansion-panel-header fxLayout="row wrap">
|
||||
<mat-expansion-panel-header fxLayout="row wrap" class="fill-width">
|
||||
<mat-panel-title fxFlex="60">
|
||||
<mat-slide-toggle formControlName="useCellContentFunction" (click)="$event.stopPropagation()"
|
||||
<mat-slide-toggle class="mat-slide" formControlName="useCellContentFunction" (click)="$event.stopPropagation()"
|
||||
fxLayoutAlign="center">
|
||||
{{ 'widgets.table.use-cell-content-function' | translate }}
|
||||
</mat-slide-toggle>
|
||||
@ -73,30 +107,5 @@
|
||||
</tb-js-func>
|
||||
</ng-template>
|
||||
</mat-expansion-panel>
|
||||
</fieldset>
|
||||
<mat-form-field fxFlex class="mat-block">
|
||||
<mat-label translate>widgets.table.default-column-visibility</mat-label>
|
||||
<mat-select formControlName="defaultColumnVisibility">
|
||||
<mat-option [value]="'visible'">
|
||||
{{ 'widgets.table.column-visibility-visible' | translate }}
|
||||
</mat-option>
|
||||
<mat-option [value]="'hidden'">
|
||||
{{ 'widgets.table.column-visibility-hidden' | translate }}
|
||||
</mat-option>
|
||||
<mat-option [value]="'hidden-mobile'">
|
||||
{{ 'widgets.table.column-visibility-hidden-mobile' | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field fxFlex class="mat-block">
|
||||
<mat-label translate>widgets.table.column-selection-to-display</mat-label>
|
||||
<mat-select formControlName="columnSelectionToDisplay">
|
||||
<mat-option [value]="'enabled'">
|
||||
{{ 'widgets.table.column-selection-to-display-enabled' | translate }}
|
||||
</mat-option>
|
||||
<mat-option [value]="'disabled'">
|
||||
{{ 'widgets.table.column-selection-to-display-disabled' | translate }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</section>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
@ -16,6 +16,10 @@
|
||||
@import '../../../../../../../scss/constants';
|
||||
|
||||
:host {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
|
||||
.tb-widget-settings {
|
||||
.fields-group {
|
||||
padding: 0 16px 8px;
|
||||
|
||||
@ -318,6 +318,11 @@ export interface DataKey extends KeyInfo {
|
||||
_hash?: number;
|
||||
}
|
||||
|
||||
export enum DataKeyConfigMode {
|
||||
general = 'general',
|
||||
advanced = 'advanced'
|
||||
}
|
||||
|
||||
export enum DatasourceType {
|
||||
function = 'function',
|
||||
device = 'device',
|
||||
|
||||
@ -1130,6 +1130,7 @@
|
||||
},
|
||||
"datakey": {
|
||||
"settings": "Settings",
|
||||
"general": "General",
|
||||
"advanced": "Advanced",
|
||||
"key": "Key",
|
||||
"label": "Label",
|
||||
@ -5231,6 +5232,7 @@
|
||||
"display-alarm-activity": "Display alarm activity",
|
||||
"allow-alarms-assign": "Allow alarms assignment",
|
||||
"columns": "Columns",
|
||||
"column-settings": "Column settings",
|
||||
"remove-column": "Remove column",
|
||||
"add-column": "Add column",
|
||||
"no-columns": "No columns configured"
|
||||
|
||||
@ -224,6 +224,8 @@ div {
|
||||
line-height: var(--mdc-typography-caption-line-height, 20px);
|
||||
font-weight: var(--mdc-typography-caption-font-weight, 400);
|
||||
letter-spacing: var(--mdc-typography-caption-letter-spacing, 0.0333333333em);
|
||||
color: rgba(0, 0, 0, 0.6);
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.mat-caption {
|
||||
@ -1199,11 +1201,26 @@ mat-label {
|
||||
&.no-padding-bottom {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
&.no-padding {
|
||||
padding: 0;
|
||||
}
|
||||
&.stroked {
|
||||
box-shadow: none;
|
||||
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||
border-radius: 6px;
|
||||
}
|
||||
&.tb-slide-toggle {
|
||||
padding: 0;
|
||||
.mat-expansion-panel {
|
||||
padding: 16px;
|
||||
.mat-expansion-panel-header {
|
||||
height: 32px;
|
||||
.mat-slide {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.mat-expansion-panel {
|
||||
&.tb-settings {
|
||||
box-shadow: none;
|
||||
@ -1220,6 +1237,11 @@ mat-label {
|
||||
flex: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
&.fill-width {
|
||||
.mat-content {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background: none;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user