UI: Improve data keys config. Fix datasource type processing.

This commit is contained in:
Igor Kulikov 2023-06-20 18:52:13 +03:00
parent 6b8cbbd3c9
commit 1ec37d7685
20 changed files with 305 additions and 176 deletions

View File

@ -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,

View File

@ -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) {

View File

@ -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) {

View File

@ -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

View File

@ -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">

View File

@ -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;
}
}
}

View File

@ -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,

View File

@ -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>

View File

@ -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);
}
}
}
}

View File

@ -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,

View File

@ -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"

View File

@ -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 {

View File

@ -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>

View File

@ -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;

View File

@ -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

View File

@ -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>

View File

@ -16,6 +16,10 @@
@import '../../../../../../../scss/constants';
:host {
display: flex;
flex-direction: column;
gap: 16px;
.tb-widget-settings {
.fields-group {
padding: 0 16px 8px;

View File

@ -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',

View File

@ -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"

View File

@ -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;
}