UI: Remove flex layout in gateway widgets

This commit is contained in:
Vladyslav_Prykhodko 2024-10-14 17:18:04 +03:00
parent ae8cf7d2e5
commit 06eb4656cb
32 changed files with 682 additions and 836 deletions

View File

@ -17,8 +17,7 @@
-->
<tb-json-object-edit
fillHeight="true"
class="tb-flex config-container"
fxLayout="column"
class="flex flex-col config-container"
jsonRequired
label="{{ 'gateway.configuration' | translate }}"
[formControl]="advancedFormControl"

View File

@ -152,12 +152,11 @@
</mat-icon>
</mat-form-field>
</section>
<tb-error style="margin-top: -12px; display: block;" fxFlex="100"
<tb-error style="margin-top: -12px; display: block;"
*ngIf="basicFormGroup.get('thingsboard.security.type').value === 'usernamePassword'"
[error]="basicFormGroup.get('thingsboard.security').hasError('atLeastOne') ?
('device.client-id-or-user-name-necessary' | translate) : ''"></tb-error>
<tb-file-input
fxFlex="100"
hint="{{ 'gateway.hints.ca-cert' | translate }}"
*ngIf="basicFormGroup.get('thingsboard.security.type').value.toLowerCase().includes('tls')"
formControlName="caCert"
@ -175,7 +174,7 @@
<ng-template matTabContent>
<div formGroupName="logs" class="mat-content mat-padding configuration-block">
<div class="tb-form-panel no-padding-bottom">
<div fxLayout="column">
<div class="flex flex-col">
<mat-form-field appearance="outline">
<mat-label translate>gateway.logs.date-format</mat-label>
<input matInput formControlName="dateFormat"/>
@ -594,7 +593,7 @@
<div class="tb-form-panel-title" translate>gateway.statistics.commands</div>
<div class="tb-form-panel-hint" translate>gateway.hints.commands</div>
<ng-container formGroupName="statistics">
<div fxLayout="row" formArrayName="commands" class="statistics-container"
<div formArrayName="commands" class="flex flex-row statistics-container"
*ngFor="let commandControl of commandFormArray().controls; let $index = index">
<section [formGroupName]="$index" class="tb-form-panel stroked no-padding-bottom no-gap command-container">
<section class="tb-form-row no-border no-padding tb-standard-fields column-xs">

View File

@ -24,7 +24,7 @@
<div class="tb-form-panel stroked tb-flex">
<ng-container [formGroup]="keyControl">
<mat-expansion-panel class="tb-settings" [expanded]="last">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex flex-row flex-wrap">
<mat-panel-title>
<ng-container *ngIf="keysType !== MappingKeysType.RPC_METHODS">
<div tbTruncateWithTooltip class="title-container">
@ -40,25 +40,23 @@
*ngIf="keysType !== MappingKeysType.CUSTOM && keysType !== MappingKeysType.RPC_METHODS">
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.platform-side</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required"
tb-hint-tooltip-icon="{{ 'gateway.JSONPath-hint' | translate }}">
{{ 'gateway.key' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="key" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.key-required') | translate"
*ngIf="keyControl.get('key').hasError('required') &&
keyControl.get('key').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="key" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.key-required') | translate"
*ngIf="keyControl.get('key').hasError('required') &&
keyControl.get('key').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-panel stroked">
@ -98,12 +96,12 @@
</mat-select>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required"
tb-hint-tooltip-icon="{{ 'gateway.JSONPath-hint' | translate }}">
{{ 'gateway.value' | translate }}
</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic" class="tb-flex no-gap">
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="tb-flex no-gap">
<input matInput required formControlName="value"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -127,25 +125,23 @@
</div>
</div>
<div class="tb-form-panel no-border no-padding" *ngIf="keysType === MappingKeysType.CUSTOM">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.key</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="key" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.key-required') | translate"
*ngIf="keyControl.get('key').hasError('required') && keyControl.get('key').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="key" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.key-required') | translate"
*ngIf="keyControl.get('key').hasError('required') && keyControl.get('key').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.value</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex tb-suffix-absolute">
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex tb-suffix-absolute">
<input matInput required formControlName="value"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -160,27 +156,25 @@
</div>
</div>
<div class="tb-form-panel no-border no-padding" *ngIf="keysType === MappingKeysType.RPC_METHODS">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.method-name' | translate }}">
{{ 'gateway.method-name' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="method" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.method-required') | translate"
*ngIf="keyControl.get('method').hasError('required') && keyControl.get('method').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="method" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.method-required') | translate"
*ngIf="keyControl.get('method').hasError('required') && keyControl.get('method').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-panel stroked tb-flex">
<mat-expansion-panel class="tb-settings">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex flex-wrap">
<mat-panel-title>
<div class="title-container" tb-hint-tooltip-icon="{{ 'gateway.hints.arguments' | translate }}">
{{ 'gateway.arguments' | translate }}{{' (' + keyControl.get('arguments').value?.length + ')'}}

View File

@ -16,13 +16,13 @@
-->
<div class="tb-mapping-table tb-absolute-fill">
<div fxFlex fxLayout="column" class="tb-mapping-table-content">
<mat-toolbar class="mat-mdc-table-toolbar" [fxShow]="!textSearchMode">
<div class="tb-mapping-table-content flex flex-col">
<mat-toolbar class="mat-mdc-table-toolbar" [class.!hidden]="textSearchMode">
<div class="mat-toolbar-tools" *ngIf="(dataSource.isEmpty() | async) === false">
<div fxLayout="row" fxLayoutAlign="start center" fxLayout.xs="column" fxLayoutAlign.xs="center start" class="title-container">
<div class="title-container">
<span class="tb-mapping-table-title">{{mappingTypeTranslationsMap.get(mappingType) | translate}}</span>
</div>
<span fxFlex></span>
<span class="flex-1"></span>
<button mat-icon-button
(click)="manageMapping($event)"
matTooltip="{{ 'action.add' | translate }}"
@ -37,14 +37,14 @@
</button>
</div>
</mat-toolbar>
<mat-toolbar class="mat-mdc-table-toolbar" [fxShow]="textSearchMode">
<mat-toolbar class="mat-mdc-table-toolbar" [class.!hidden]="!textSearchMode">
<div class="mat-toolbar-tools">
<button mat-icon-button
matTooltip="{{ 'action.search' | translate }}"
matTooltipPosition="above">
<mat-icon>search</mat-icon>
</button>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>&nbsp;</mat-label>
<input #searchInput matInput
[formControl]="textSearch"
@ -70,11 +70,11 @@
</mat-cell>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<mat-header-cell *matHeaderCellDef
[ngStyle.gt-md]="{ minWidth: '96px', maxWidth: '96px', width: '96px', textAlign: 'center'}">
<mat-header-cell *matHeaderCellDef>
<div class="gt-md:!hidden" style="width: 48px; min-width: 48px; max-width: 48px;"></div>
<div class="lt-lg:!hidden" [style]="{ minWidth: '96px', textAlign: 'center'}"></div>
</mat-header-cell>
<mat-cell *matCellDef="let mapping; let i = index"
[ngStyle.gt-md]="{ minWidth: '96px', maxWidth: '96px', width: '96px'}">
<mat-cell *matCellDef="let mapping; let i = index">
<ng-template #rowActions>
<button mat-icon-button
matTooltip="{{ 'action.edit' | translate }}"
@ -89,10 +89,11 @@
<tb-icon>delete</tb-icon>
</button>
</ng-template>
<div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
<div class="flex flex-1 flex-row justify-end items-stretch lt-lg:!hidden"
[style]="{ minWidth: '96px', textAlign: 'center'}">
<ng-container [ngTemplateOutlet]="rowActions"></ng-container>
</div>
<div fxHide fxShow.lt-lg fxFlex fxLayout="row" fxLayoutAlign="end">
<div class="gt-md:!hidden">
<button mat-icon-button
(click)="$event.stopPropagation()"
[matMenuTriggerFor]="cellActionsMenu">
@ -104,11 +105,11 @@
</div>
</mat-cell>
</ng-container>
<mat-header-row [ngClass]="{'mat-row-select': true}" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-header-row class="mat-row-select" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row *matRowDef="let mapping; columns: displayedColumns;"></mat-row>
</table>
<section [fxShow]="!textSearchMode && (dataSource.isEmpty() | async)" fxLayoutAlign="center center"
class="mat-headline-5 tb-absolute-fill tb-add-new">
<section [class.!hidden]="textSearchMode || (dataSource.isEmpty() | async) === false"
class="mat-headline-5 tb-absolute-fill tb-add-new justify-center items-center">
<button mat-button class="connector"
(click)="manageMapping($event)">
<mat-icon class="tb-mat-96">add</mat-icon>
@ -116,9 +117,8 @@
</button>
</section>
</div>
<span [fxShow]="textSearchMode && (dataSource.isEmpty() | async)"
fxLayoutAlign="center center"
class="no-data-found" translate>
<span [class.!hidden]="!textSearchMode || (dataSource.isEmpty() | async) === false"
class="no-data-found justify-center items-center" translate>
widget.no-data-found
</span>
</div>

View File

@ -25,7 +25,7 @@
<mat-tab label="{{ 'gateway.server-config' | translate }}">
<div class="tb-form-panel no-border no-padding padding-top">
<div class="tb-form-hint tb-primary-fill tb-flex center">{{ 'gateway.hints.modbus-server' | translate }}</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" [formControl]="enableSlaveControl">
<mat-label>
{{ 'gateway.enable' | translate }}

View File

@ -24,7 +24,7 @@
<div class="tb-form-panel stroked tb-flex">
<ng-container [formGroup]="keyControl">
<mat-expansion-panel class="tb-settings" [expanded]="last">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex-wrap">
<mat-panel-title>
<div *ngIf="isMaster else tagName" class="title-container" tbTruncateWithTooltip>
{{ keyControl.get('tag').value }}{{ '-' }}{{ keyControl.get('value').value }}
@ -56,104 +56,93 @@
</div>
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.platform-side</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.key' | translate }}" translate>
gateway.key
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="tag" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.key-required') | translate"
*ngIf="keyControl.get('tag').hasError('required') &&
keyControl.get('tag').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="tag" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.key-required') | translate"
*ngIf="keyControl.get('tag').hasError('required') &&
keyControl.get('tag').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.connector-side</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>
gateway.type
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="type">
<mat-option *ngFor="let type of modbusDataTypes" [value]="type">{{ type }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="type">
<mat-option *ngFor="let type of modbusDataTypes" [value]="type">{{ type }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div *ngIf="withFunctionCode" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="withFunctionCode" class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.function-code</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="functionCode">
<mat-option
*ngFor="let code of functionCodesMap.get(keyControl.get('id').value) || defaultFunctionCodes"
[value]="code"
>
{{ ModbusFunctionCodeTranslationsMap.get(code) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="functionCode">
<mat-option
*ngFor="let code of functionCodesMap.get(keyControl.get('id').value) || defaultFunctionCodes"
[value]="code"
>
{{ ModbusFunctionCodeTranslationsMap.get(code) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.objects-count' | translate }}" translate>gateway.objects-count</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input
matInput
type="number"
min="1"
max="50000"
name="value"
formControlName="objectsCount"
placeholder="{{ 'gateway.set' | translate }}"
[readonly]="!ModbusEditableDataTypes.includes(keyControl.get('type').value)"
/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.objects-count-required') | translate"
*ngIf="keyControl.get('objectsCount').hasError('required') &&
keyControl.get('objectsCount').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input
matInput
type="number"
min="1"
max="50000"
name="value"
formControlName="objectsCount"
placeholder="{{ 'gateway.set' | translate }}"
[readonly]="!ModbusEditableDataTypes.includes(keyControl.get('type').value)"
/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.objects-count-required') | translate"
*ngIf="keyControl.get('objectsCount').hasError('required') &&
keyControl.get('objectsCount').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.address' | translate }}" translate>gateway.address</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" max="50000" name="value" formControlName="address" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.address-required') | translate"
*ngIf="keyControl.get('address').hasError('required') &&
keyControl.get('address').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" max="50000" name="value" formControlName="address" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.address-required') | translate"
*ngIf="keyControl.get('address').hasError('required') &&
keyControl.get('address').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div *ngIf="showModifiersMap.get(keyControl.get('id').value)" class="tb-form-panel stroked tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="enableModifiersControlMap.get(keyControl.get('id').value).value">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex-wrap">
<mat-panel-title>
<mat-slide-toggle
fxLayoutAlign="center"
[formControl]="enableModifiersControlMap.get(keyControl.get('id').value)"
class="mat-slide"
(click)="$event.stopPropagation()"
@ -165,30 +154,28 @@
</mat-panel-title>
</mat-expansion-panel-header>
<div class="tb-flex no-gap">
<div class="tb-form-row column-xs tb-flex full-width" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs tb-flex full-width">
<div class="fixed-title-width" translate>gateway.type</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap fill-width" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="modifierType">
<mat-select-trigger>
<div class="tb-flex align-center">
<mat-icon class="tb-mat-18" [svgIcon]="ModifierTypesMap.get(keyControl.get('modifierType').value)?.icon"></mat-icon>
<span>{{ ModifierTypesMap.get(keyControl.get('modifierType').value)?.name | translate}}</span>
</div>
</mat-select-trigger>
<mat-option *ngFor="let modifierType of modifierTypes" [value]="modifierType">
<mat-icon class="tb-mat-20" svgIcon="{{ ModifierTypesMap.get(modifierType).icon }}">
</mat-icon>
<span>{{ ModifierTypesMap.get(modifierType).name | translate }}</span>
</mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap fill-width" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="modifierType">
<mat-select-trigger>
<div class="tb-flex align-center">
<mat-icon class="tb-mat-18" [svgIcon]="ModifierTypesMap.get(keyControl.get('modifierType').value)?.icon"></mat-icon>
<span>{{ ModifierTypesMap.get(keyControl.get('modifierType').value)?.name | translate}}</span>
</div>
</mat-select-trigger>
<mat-option *ngFor="let modifierType of modifierTypes" [value]="modifierType">
<mat-icon class="tb-mat-20" svgIcon="{{ ModifierTypesMap.get(modifierType).icon }}">
</mat-icon>
<span>{{ ModifierTypesMap.get(modifierType).name | translate }}</span>
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.value</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex tb-suffix-absolute">
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex tb-suffix-absolute">
<input matInput required formControlName="modifierValue" step="0.1" type="number"
placeholder="{{ 'gateway.set' | translate }}" />
<mat-icon matSuffix
@ -204,22 +191,20 @@
</div>
</mat-expansion-panel>
</div>
<div *ngIf="isMaster" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="isMaster" class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.value</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="value" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.value-required') | translate"
*ngIf="keyControl.get('value').hasError('required') &&
keyControl.get('value').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="value" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.value-required') | translate"
*ngIf="keyControl.get('value').hasError('required') &&
keyControl.get('value').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<tb-report-strategy
*ngIf="withReportStrategy"

View File

@ -19,13 +19,13 @@
<div class="tb-form-panel no-border no-padding padding-top">
<div class="tb-form-hint tb-primary-fill tb-flex center">{{ 'gateway.hints.modbus-master' | translate }}</div>
</div>
<div fxFlex fxLayout="column" class="tb-master-table-content">
<mat-toolbar class="mat-mdc-table-toolbar" [fxShow]="!textSearchMode">
<div class="tb-master-table-content flex flex-col">
<mat-toolbar class="mat-mdc-table-toolbar" [class.!hidden]="textSearchMode">
<div class="mat-toolbar-tools" *ngIf="(dataSource.isEmpty() | async) === false">
<div fxLayout="row" fxLayoutAlign="start center" fxLayout.xs="column" fxLayoutAlign.xs="center start" class="title-container">
<div class="title-container">
<span class="tb-master-table-title">{{ 'gateway.servers-slaves' | translate}}</span>
</div>
<span fxFlex></span>
<span class="flex-1"></span>
<button mat-icon-button
(click)="manageSlave($event)"
matTooltip="{{ 'action.add' | translate }}"
@ -40,14 +40,14 @@
</button>
</div>
</mat-toolbar>
<mat-toolbar class="mat-mdc-table-toolbar" [fxShow]="textSearchMode">
<mat-toolbar class="mat-mdc-table-toolbar" [class.!hidden]="!textSearchMode">
<div class="mat-toolbar-tools">
<button mat-icon-button
matTooltip="{{ 'action.search' | translate }}"
matTooltipPosition="above">
<mat-icon>search</mat-icon>
</button>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>&nbsp;</mat-label>
<input #searchInput matInput
[formControl]="textSearch"
@ -95,11 +95,11 @@
</mat-cell>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<mat-header-cell *matHeaderCellDef
[ngStyle.gt-md]="{ minWidth: '96px', maxWidth: '96px', width: '96px', textAlign: 'center'}">
<mat-header-cell *matHeaderCellDef>
<div class="gt-md:!hidden" style="width: 48px; min-width: 48px; max-width: 48px;"></div>
<div class="lt-lg:!hidden" [style]="{ minWidth: '96px', textAlign: 'center'}"></div>
</mat-header-cell>
<mat-cell *matCellDef="let slave; let i = index"
[ngStyle.gt-md]="{ minWidth: '96px', maxWidth: '96px', width: '96px'}">
<mat-cell *matCellDef="let slave; let i = index">
<ng-template #rowActions>
<button mat-icon-button
matTooltip="{{ 'action.edit' | translate }}"
@ -114,10 +114,11 @@
<tb-icon>delete</tb-icon>
</button>
</ng-template>
<div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
<div class="flex flex-1 flex-row justify-end items-stretch lt-lg:!hidden"
[style]="{ minWidth: '96px', textAlign: 'center'}">
<ng-container [ngTemplateOutlet]="rowActions"></ng-container>
</div>
<div fxHide fxShow.lt-lg fxFlex fxLayout="row" fxLayoutAlign="end">
<div class="gt-md:!hidden">
<button mat-icon-button
(click)="$event.stopPropagation()"
[matMenuTriggerFor]="cellActionsMenu">
@ -129,11 +130,11 @@
</div>
</mat-cell>
</ng-container>
<mat-header-row [ngClass]="{'mat-row-select': true}" *matHeaderRowDef="['deviceName', 'info', 'unitId', 'type', 'actions']; sticky: true"></mat-header-row>
<mat-header-row class="mat-row-select" *matHeaderRowDef="['deviceName', 'info', 'unitId', 'type', 'actions']; sticky: true"></mat-header-row>
<mat-row *matRowDef="let slave; columns: ['deviceName', 'info', 'unitId', 'type', 'actions']"></mat-row>
</table>
<section [fxShow]="!textSearchMode && (dataSource.isEmpty() | async)" fxLayoutAlign="center center"
class="mat-headline-5 tb-absolute-fill tb-add-new">
<section [class.!hidden]="textSearchMode || (dataSource.isEmpty() | async) === false"
class="mat-headline-5 tb-absolute-fill tb-add-new justify-center items-center">
<button mat-button class="connector"
(click)="manageSlave($event)">
<mat-icon class="tb-mat-96">add</mat-icon>
@ -141,9 +142,8 @@
</button>
</section>
</div>
<span [fxShow]="textSearchMode && (dataSource.isEmpty() | async)"
fxLayoutAlign="center center"
class="no-data-found" translate>
<span [class.!hidden]="!textSearchMode || (dataSource.isEmpty() | async) === false"
class="no-data-found justify-center items-center" translate>
widget.no-data-found
</span>
</div>

View File

@ -56,7 +56,7 @@
</mat-form-field>
</div>
</div>
<div *ngIf="isMaster" class="tb-form-row" fxLayoutAlign="space-between center">
<div *ngIf="isMaster" class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="reqclicert">
<mat-label>
{{ 'gateway.request-client-certificate' | translate }}

View File

@ -25,11 +25,8 @@
</div>
<div class="tb-form-panel no-border no-padding padding-top">
<div *ngIf="protocolType !== ModbusProtocolType.Serial"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.host' | translate }}" translate>gateway.host</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="host" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -42,14 +39,10 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div *ngIf="protocolType !== ModbusProtocolType.Serial else serialPort"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.port' | translate }}" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="{{portLimits.MIN}}" max="{{portLimits.MAX}}"
name="value" formControlName="port" placeholder="{{ 'gateway.set' | translate }}"/>
@ -65,12 +58,10 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<ng-template #serialPort>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.serial-port' | translate }}" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="serialPort" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -82,26 +73,22 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
</ng-template>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.framer-type' | translate }}" translate>
gateway.method
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="method">
<mat-option *ngFor="let method of protocolType === ModbusProtocolType.Serial ? modbusSerialMethodTypes : modbusMethodTypes"
[value]="method">{{ ModbusMethodLabelsMap.get(method) }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.unit-id' | translate }}" translate>gateway.unit-id</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="unitId" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -114,11 +101,9 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.device-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceName" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -131,11 +116,9 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.device-profile</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceType" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -148,31 +131,26 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.poll-period' | translate }}">
<span tbTruncateWithTooltip translate>
gateway.poll-period
</span>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="pollPeriod" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div *ngIf="protocolType === ModbusProtocolType.Serial" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="protocolType === ModbusProtocolType.Serial" class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.baudrate' | translate }}" translate>gateway.baudrate</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="baudrate">
<mat-option *ngFor="let rate of modbusBaudrates" [value]="rate">{{ rate }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="sendDataToThingsBoard">
<mat-label>
{{ 'gateway.send-data-to-platform' | translate }}
@ -187,31 +165,27 @@
</mat-panel-title>
</mat-expansion-panel-header>
<div class="tb-form-panel no-border no-padding padding-top">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.byte-order' | translate }}" translate>gateway.byte-order</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="byteOrder">
<mat-option *ngFor="let order of modbusOrderType" [value]="order">{{ order }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.word-order' | translate }}" translate>gateway.word-order</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="wordOrder">
<mat-option *ngFor="let order of modbusOrderType" [value]="order">{{ order }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div *ngIf="protocolType !== ModbusProtocolType.Serial" class="tb-form-panel stroked tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="showSecurityControl.value">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex-wrap">
<mat-panel-title>
<mat-slide-toggle fxLayoutAlign="center" [formControl]="showSecurityControl" class="mat-slide" (click)="$event.stopPropagation()">
<mat-slide-toggle [formControl]="showSecurityControl" class="mat-slide" (click)="$event.stopPropagation()">
<mat-label>
{{ 'gateway.tls-connection' | translate }}
</mat-label>
@ -222,45 +196,35 @@
</mat-expansion-panel>
</div>
<ng-container [formGroup]="slaveConfigFormGroup.get('identity')">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.vendor-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="vendorName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.product-code</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="productCode" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.vendor-url</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="vendorUrl" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.product-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="productName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.model-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="modelName" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
</ng-container>
</div>

View File

@ -18,7 +18,7 @@
<div class="slaves-config-container">
<mat-toolbar color="primary">
<h2>{{ 'gateway.server-slave' | translate }}</h2>
<span fxFlex></span>
<span class="flex-1"></span>
<div [tb-help]="modbusHelpLink"></div>
<button mat-icon-button
(click)="cancel()"
@ -37,11 +37,8 @@
</div>
<div class="tb-form-panel no-border no-padding padding-top">
<div *ngIf="protocolType !== ModbusProtocolType.Serial"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.host' | translate }}" translate>gateway.host</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="host" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -54,14 +51,10 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div *ngIf="protocolType !== ModbusProtocolType.Serial else serialPort"
class="tb-form-row column-xs"
fxLayoutAlign="space-between center"
>
class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.port' | translate }}" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="{{portLimits.MIN}}" max="{{portLimits.MAX}}"
name="value" formControlName="port" placeholder="{{ 'gateway.set' | translate }}"/>
@ -77,12 +70,10 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<ng-template #serialPort>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.serial-port' | translate }}" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="serialPort" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -95,63 +86,52 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
</ng-template>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.framer-type' | translate }}" translate>
gateway.method
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="method">
<mat-option *ngFor="let method of protocolType === ModbusProtocolType.Serial ? modbusSerialMethodTypes : modbusMethodTypes"
[value]="method">{{ ModbusMethodLabelsMap.get(method) }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
<ng-container *ngIf="protocolType === ModbusProtocolType.Serial">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.baudrate' | translate }}" translate>gateway.baudrate</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="baudrate">
<mat-option *ngFor="let rate of modbusBaudrates" [value]="rate">{{ rate }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.bytesize' | translate }}" translate>gateway.bytesize</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="bytesize">
<mat-option *ngFor="let size of modbusByteSizes" [value]="size">{{ size }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.stopbits' | translate }}" translate>gateway.stopbits</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="stopbits" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.parity' | translate }}" translate>gateway.parity</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="parity">
<mat-option *ngFor="let parity of modbusParities" [value]="parity">{{ ModbusParityLabelsMap.get(parity) }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="strict">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.strict' | translate }}">
{{ 'gateway.strict' | translate }}
@ -159,9 +139,8 @@
</mat-slide-toggle>
</div>
</ng-container>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.unit-id' | translate }}" translate>gateway.unit-id</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="unitId" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -174,11 +153,9 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.device-name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceName" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -191,11 +168,9 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.device-profile</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceType" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -208,9 +183,8 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div *ngIf="data.hideNewFields else reportStrategy" class="tb-form-row" fxLayoutAlign="space-between center">
<div *ngIf="data.hideNewFields else reportStrategy" class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="sendDataOnlyOnChange">
<mat-label>
{{ 'gateway.send-data-on-change' | translate }}
@ -228,39 +202,33 @@
</mat-panel-title>
</mat-expansion-panel-header>
<div class="tb-form-panel no-border no-padding padding-top">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.connection-timeout' | translate }}" translate>gateway.connection-timeout</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="timeout" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.byte-order' | translate }}" translate>gateway.byte-order</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="byteOrder">
<mat-option *ngFor="let order of modbusOrderType" [value]="order">{{ order }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.word-order' | translate }}" translate>gateway.word-order</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="wordOrder">
<mat-option *ngFor="let order of modbusOrderType" [value]="order">{{ order }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div *ngIf="protocolType !== ModbusProtocolType.Serial" class="tb-form-panel stroked tb-slide-toggle">
<mat-expansion-panel class="tb-settings" [expanded]="showSecurityControl.value">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex-wrap">
<mat-panel-title>
<mat-slide-toggle fxLayoutAlign="center" [formControl]="showSecurityControl" class="mat-slide" (click)="$event.stopPropagation()">
<mat-slide-toggle [formControl]="showSecurityControl" class="mat-slide justify-start" (click)="$event.stopPropagation()">
<mat-label>
{{ 'gateway.tls-connection' | translate }}
</mat-label>
@ -270,62 +238,54 @@
<tb-modbus-security-config class="security-config" formControlName="security"></tb-modbus-security-config>
</mat-expansion-panel>
</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="retries">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.retries' | translate }}">
{{ 'gateway.retries' | translate }}
</mat-label>
</mat-slide-toggle>
</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="retryOnEmpty">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.retries-on-empty' | translate }}">
{{ 'gateway.retries-on-empty' | translate }}
</mat-label>
</mat-slide-toggle>
</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="retryOnInvalid">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.retries-on-invalid' | translate }}">
{{ 'gateway.retries-on-invalid' | translate }}
</mat-label>
</mat-slide-toggle>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width-260 tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.poll-period' | translate }}">
<span tbTruncateWithTooltip translate>
gateway.poll-period
</span>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="pollPeriod" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width-260 tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.connect-attempt-time' | translate }}" translate>gateway.connect-attempt-time</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="connectAttemptTimeMs" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width-260 tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.connect-attempt-count' | translate }}" translate>gateway.connect-attempt-count</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="connectAttemptCount" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width-260 tb-required" tb-hint-tooltip-icon="{{ 'gateway.hints.modbus.wait-after-failed-attempts' | translate }}" translate>gateway.wait-after-failed-attempts</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="waitAfterFailedAttemptsMs" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
</div>
</mat-expansion-panel>
@ -336,7 +296,7 @@
</div>
</div>
</div>
<div mat-dialog-actions fxLayoutAlign="end center">
<div mat-dialog-actions class="justify-end">
<button mat-button color="primary"
type="button"
cdkFocusInitial

View File

@ -17,7 +17,7 @@
-->
<ng-container *ngIf="singleMode else multipleView">
<div [formGroup]="valuesFormGroup" class="tb-form-panel no-border no-padding padding-top" fxLayout="column">
<div [formGroup]="valuesFormGroup" class="tb-form-panel no-border no-padding padding-top">
<ng-container [ngTemplateOutlet]="singleView" [ngTemplateOutletContext]="{$implicit: null}"></ng-container>
</div>
</ng-container>
@ -25,7 +25,7 @@
<ng-template #multipleView>
<mat-tab-group [formGroup]="valuesFormGroup">
<mat-tab *ngFor="let register of modbusRegisterTypes" label="{{ ModbusValuesTranslationsMap.get(register) | translate }}">
<div [formGroup]="valuesFormGroup.get(register)" class="tb-form-panel no-border no-padding padding-top" fxLayout="column">
<div [formGroup]="valuesFormGroup.get(register)" class="tb-form-panel no-border no-padding padding-top">
<ng-container [ngTemplateOutlet]="singleView" [ngTemplateOutletContext]="{$implicit: register}"></ng-container>
</div>
</mat-tab>

View File

@ -16,70 +16,62 @@
-->
<div class="tb-form-panel no-border no-padding padding-top" [formGroup]="brokerConfigFormGroup">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.host</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="host" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.host-required') | translate"
*ngIf="brokerConfigFormGroup.get('host').hasError('required')
&& brokerConfigFormGroup.get('host').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" translate>gateway.port</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="{{portLimits.MIN}}" max="{{portLimits.MAX}}"
name="value" formControlName="port" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="brokerConfigFormGroup.get('port') | getGatewayPortTooltip"
*ngIf="(brokerConfigFormGroup.get('port').hasError('required') ||
brokerConfigFormGroup.get('port').hasError('min') ||
brokerConfigFormGroup.get('port').hasError('max')) &&
brokerConfigFormGroup.get('port').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.mqtt-version</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="version">
<mat-option *ngFor="let version of mqttVersions" [value]="version.value">{{ version.name }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width" translate>gateway.client-id</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="clientId" placeholder="{{ 'gateway.set' | translate }}"/>
<button type="button"
matSuffix
mat-icon-button
aria-label="Generate"
matTooltip="{{ 'gateway.generate-client-id' | translate }}"
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="host" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
(click)="generate('clientId')"
*ngIf="!brokerConfigFormGroup.get('clientId').value">
<mat-icon>autorenew</mat-icon>
</button>
</mat-form-field>
</div>
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.host-required') | translate"
*ngIf="brokerConfigFormGroup.get('host').hasError('required')
&& brokerConfigFormGroup.get('host').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.port</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="{{portLimits.MIN}}" max="{{portLimits.MAX}}"
name="value" formControlName="port" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="brokerConfigFormGroup.get('port') | getGatewayPortTooltip"
*ngIf="(brokerConfigFormGroup.get('port').hasError('required') ||
brokerConfigFormGroup.get('port').hasError('min') ||
brokerConfigFormGroup.get('port').hasError('max')) &&
brokerConfigFormGroup.get('port').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.mqtt-version</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="version">
<mat-option *ngFor="let version of mqttVersions" [value]="version.value">{{ version.name }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.client-id</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="clientId" placeholder="{{ 'gateway.set' | translate }}"/>
<button type="button"
matSuffix
mat-icon-button
aria-label="Generate"
matTooltip="{{ 'gateway.generate-client-id' | translate }}"
matTooltipPosition="above"
(click)="generate('clientId')"
*ngIf="!brokerConfigFormGroup.get('clientId').value">
<mat-icon>autorenew</mat-icon>
</button>
</mat-form-field>
</div>
<tb-security-config formControlName="security">
</tb-security-config>

View File

@ -16,48 +16,44 @@
-->
<div class="tb-form-panel no-border no-padding padding-top" [formGroup]="workersConfigFormGroup">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" [style.width.%]="50"
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" style="width: 50%"
tb-hint-tooltip-icon="{{ 'gateway.max-number-of-workers-hint' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.max-number-of-workers' | translate }}</div>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" type="number" min="1" formControlName="maxNumberOfWorkers"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.max-number-of-workers-required') | translate"
*ngIf="workersConfigFormGroup.get('maxNumberOfWorkers').hasError('min') ||
(workersConfigFormGroup.get('maxNumberOfWorkers').hasError('required') &&
workersConfigFormGroup.get('maxNumberOfWorkers').touched)"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" type="number" min="1" formControlName="maxNumberOfWorkers"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.max-number-of-workers-required') | translate"
*ngIf="workersConfigFormGroup.get('maxNumberOfWorkers').hasError('min') ||
(workersConfigFormGroup.get('maxNumberOfWorkers').hasError('required') &&
workersConfigFormGroup.get('maxNumberOfWorkers').touched)"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="fixed-title-width tb-required" [style.width.%]="50"
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" style="width: 50%"
tb-hint-tooltip-icon="{{ 'gateway.max-messages-queue-for-worker-hint' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.max-messages-queue-for-worker' | translate }}</div>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" type="number" min="1" formControlName="maxMessageNumberPerWorker"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.max-messages-queue-for-worker-required') | translate"
*ngIf="workersConfigFormGroup.get('maxMessageNumberPerWorker').hasError('min') ||
(workersConfigFormGroup.get('maxMessageNumberPerWorker').hasError('required') &&
workersConfigFormGroup.get('maxMessageNumberPerWorker').touched)"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" type="number" min="1" formControlName="maxMessageNumberPerWorker"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.max-messages-queue-for-worker-required') | translate"
*ngIf="workersConfigFormGroup.get('maxMessageNumberPerWorker').hasError('min') ||
(workersConfigFormGroup.get('maxMessageNumberPerWorker').hasError('required') &&
workersConfigFormGroup.get('maxMessageNumberPerWorker').touched)"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
</div>

View File

@ -16,126 +16,114 @@
-->
<div class="tb-form-panel no-border no-padding padding-top" [formGroup]="serverConfigFormGroup">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tbTruncateWithTooltip translate>gateway.server-url</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="url" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.server-url-required') | translate"
*ngIf="serverConfigFormGroup.get('url').hasError('required') &&
serverConfigFormGroup.get('url').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="url" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="('gateway.server-url-required') | translate"
*ngIf="serverConfigFormGroup.get('url').hasError('required') &&
serverConfigFormGroup.get('url').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.opc-timeout' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.timeout' | translate }}</div>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="1000" name="value" formControlName="timeoutInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.timeout-error' | translate: {min: 1000}"
*ngIf="(serverConfigFormGroup.get('timeoutInMillis').hasError('required') ||
serverConfigFormGroup.get('timeoutInMillis').hasError('min')) &&
serverConfigFormGroup.get('timeoutInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="1000" name="value" formControlName="timeoutInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.timeout-error' | translate: {min: 1000}"
*ngIf="(serverConfigFormGroup.get('timeoutInMillis').hasError('required') ||
serverConfigFormGroup.get('timeoutInMillis').hasError('min')) &&
serverConfigFormGroup.get('timeoutInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.security-policy' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.security-policy' | translate }}</div>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="security">
<mat-option *ngFor="let version of securityPolicyTypes" [value]="version.value">{{ version.name }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="security">
<mat-option *ngFor="let version of securityPolicyTypes" [value]="version.value">{{ version.name }}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.scan-period' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.scan-period' | translate }}</div>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="1000" name="value"
formControlName="scanPeriodInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.scan-period-error' | translate: {min: 1000}"
*ngIf="(serverConfigFormGroup.get('scanPeriodInMillis').hasError('required') ||
serverConfigFormGroup.get('scanPeriodInMillis').hasError('min')) &&
serverConfigFormGroup.get('scanPeriodInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="1000" name="value"
formControlName="scanPeriodInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.scan-period-error' | translate: {min: 1000}"
*ngIf="(serverConfigFormGroup.get('scanPeriodInMillis').hasError('required') ||
serverConfigFormGroup.get('scanPeriodInMillis').hasError('min')) &&
serverConfigFormGroup.get('scanPeriodInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div *ngIf="!hideNewFields" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="!hideNewFields" class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.poll-period' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.poll-period' | translate }}</div>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="50" name="value"
formControlName="pollPeriodInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.poll-period-error' | translate: {min: 50}"
*ngIf="(serverConfigFormGroup.get('pollPeriodInMillis').hasError('required') ||
serverConfigFormGroup.get('pollPeriodInMillis').hasError('min')) &&
serverConfigFormGroup.get('pollPeriodInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="50" name="value"
formControlName="pollPeriodInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.poll-period-error' | translate: {min: 50}"
*ngIf="(serverConfigFormGroup.get('pollPeriodInMillis').hasError('required') ||
serverConfigFormGroup.get('pollPeriodInMillis').hasError('min')) &&
serverConfigFormGroup.get('pollPeriodInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.hints.sub-check-period' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.sub-check-period' | translate }}</div>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="100" name="value"
formControlName="subCheckPeriodInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.sub-check-period-error' | translate: {min: 100}"
*ngIf="(serverConfigFormGroup.get('subCheckPeriodInMillis').hasError('required') ||
serverConfigFormGroup.get('subCheckPeriodInMillis').hasError('min')) &&
serverConfigFormGroup.get('subCheckPeriodInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="100" name="value"
formControlName="subCheckPeriodInMillis" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
matTooltipClass="tb-error-tooltip"
[matTooltip]="'gateway.sub-check-period-error' | translate: {min: 100}"
*ngIf="(serverConfigFormGroup.get('subCheckPeriodInMillis').hasError('required') ||
serverConfigFormGroup.get('subCheckPeriodInMillis').hasError('min')) &&
serverConfigFormGroup.get('subCheckPeriodInMillis').touched"
class="tb-error">
warning
</mat-icon>
</mat-form-field>
</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="enableSubscriptions">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.hints.enable-subscription' | translate }}">
<div tbTruncateWithTooltip>{{ 'gateway.enable-subscription' | translate }}</div>
</mat-label>
</mat-slide-toggle>
</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="showMap">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.hints.show-map' | translate }}">
{{ 'gateway.show-map' | translate }}

View File

@ -17,9 +17,9 @@
-->
<div [formGroup]="reportStrategyFormGroup" class="tb-form-panel stroked">
<mat-expansion-panel *ngIf="isExpansionMode else defaultMode" class="tb-settings" [expanded]="showStrategyControl.value">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex-wrap">
<mat-panel-title>
<mat-slide-toggle fxLayoutAlign="center" [formControl]="showStrategyControl" class="mat-slide" (click)="$event.stopPropagation()">
<mat-slide-toggle [formControl]="showStrategyControl" class="mat-slide" (click)="$event.stopPropagation()">
<mat-label>
{{ 'gateway.report-strategy.label' | translate }}
</mat-label>
@ -33,7 +33,7 @@
<ng-container [ngTemplateOutlet]="strategyFields"></ng-container>
</ng-template>
<ng-template #strategyFields>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width">{{ 'gateway.type' | translate }}</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="type">
@ -41,17 +41,15 @@
</mat-select>
</mat-form-field>
</div>
<div *ngIf="reportStrategyFormGroup.get('type').value !== ReportStrategyType.OnChange" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="reportStrategyFormGroup.get('type').value !== ReportStrategyType.OnChange" class="tb-form-row column-xs">
<div class="fixed-title-width tb-required">
<span tbTruncateWithTooltip translate>
gateway.report-strategy.report-period
</span>
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="reportPeriod" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput type="number" min="0" name="value" formControlName="reportPeriod" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</ng-template>
</div>

View File

@ -16,26 +16,26 @@
-->
<ng-container [formGroup]="rpcParametersFormGroup">
<div class="tb-form-hint tb-primary-fill tb-flex no-padding-top hint-container">
<div class="tb-form-hint tb-primary-fill no-padding-top hint-container">
{{ 'gateway.rpc.hint.modbus-response-reading' | translate }}<br>
{{ 'gateway.rpc.hint.modbus-writing-functions' | translate }}
</div>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field fxFlex="50" class="mat-block">
<div class="flex flex-row flex-1 gap-2.5">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.type' | translate }}</mat-label>
<mat-select formControlName="type">
<mat-option *ngFor="let type of modbusDataTypes" [value]="type">{{ type }}</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="50" class="mat-block">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.functionCode' | translate }}</mat-label>
<mat-select formControlName="functionCode">
<mat-option *ngFor="let code of functionCodes" [value]="code">{{ ModbusFunctionCodeTranslationsMap.get(code) | translate}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field fxFlex="50">
<div class="flex flex-row flex-1 gap-2.5">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.address' | translate }}</mat-label>
<input matInput type="number" min="0" max="50000" name="value" formControlName="address" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -48,7 +48,7 @@
warning
</mat-icon>
</mat-form-field>
<mat-form-field fxFlex="50">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.objectsCount' | translate }}</mat-label>
<input
matInput
@ -62,8 +62,8 @@
/>
</mat-form-field>
</div>
<div *ngIf="writeFunctionCodes.includes(rpcParametersFormGroup.get('functionCode').value)" fxFlex fxLayout="row">
<mat-form-field fxFlex="100">
<div *ngIf="writeFunctionCodes.includes(rpcParametersFormGroup.get('functionCode').value)" class="flex">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.value' | translate }}</mat-label>
<input matInput name="value" formControlName="value" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix

View File

@ -23,13 +23,13 @@
<mat-label>{{ 'gateway.rpc.method' | translate }}</mat-label>
<input matInput formControlName="method" placeholder="multiply"/>
</mat-form-field>
<fieldset class="tb-form-panel stroked arguments-container" fxLayout="column" formArrayName="arguments">
<fieldset class="tb-form-panel stroked arguments-container" formArrayName="arguments">
<strong>
<span class="fields-label">{{ 'gateway.rpc.arguments' | translate }}</span>
</strong>
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"
<div class="flex flex-1 justify-center items-center gap-2.5"
*ngFor="let argumentFormGroup of rpcParametersFormGroup.get('arguments')['controls']; let i = index" [formGroup]="argumentFormGroup">
<div class="tb-form-row column-xs type-container" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs type-container justify-between items-center">
<div class="tb-required" translate>gateway.type</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap fill-width" appearance="outline" subscriptSizing="dynamic">
@ -50,9 +50,9 @@
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs value-container" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs value-container justify-between item-center">
<div class="tb-required" translate>gateway.value</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex tb-suffix-absolute">
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex tb-suffix-absolute">
<ng-container [ngSwitch]="argumentFormGroup.get('type').value">
<input *ngSwitchCase="MappingValueType.STRING" matInput required formControlName="string"
placeholder="{{ 'gateway.set' | translate }}" />
@ -84,7 +84,7 @@
</button>
</div>
<button mat-raised-button
fxFlexAlign="start"
class="self-start"
(click)="addArgument()">
{{ 'gateway.rpc.add-argument' | translate }}
</button>

View File

@ -22,38 +22,36 @@
<div class="tb-form-panel stroked tb-flex">
<ng-container [formGroup]="keyControl">
<mat-expansion-panel class="tb-settings" [expanded]="last">
<mat-expansion-panel-header fxLayout="row wrap">
<mat-expansion-panel-header class="flex-wrap">
<mat-panel-title>
<div class="title-container" tbTruncateWithTooltip>{{ valueTitle(keyControl.get(keyControl.get('type').value).value) }}</div>
</mat-panel-title>
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.type</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap fill-width" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="type">
<mat-select-trigger>
<div class="tb-flex align-center">
<mat-icon class="tb-mat-18" [svgIcon]="valueTypes.get(keyControl.get('type').value)?.icon">
</mat-icon>
<span>
{{ valueTypes.get(keyControl.get('type').value)?.name | translate}}
</span>
</div>
</mat-select-trigger>
<mat-option *ngFor="let valueType of valueTypeKeys" [value]="valueType">
<mat-icon class="tb-mat-20" svgIcon="{{ valueTypes.get(valueType).icon }}">
<mat-form-field class="tb-flex no-gap fill-width" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="type">
<mat-select-trigger>
<div class="tb-flex align-center">
<mat-icon class="tb-mat-18" [svgIcon]="valueTypes.get(keyControl.get('type').value)?.icon">
</mat-icon>
<span>{{ valueTypes.get(valueType).name | translate }}</span>
</mat-option>
</mat-select>
</mat-form-field>
</div>
<span>
{{ valueTypes.get(keyControl.get('type').value)?.name | translate}}
</span>
</div>
</mat-select-trigger>
<mat-option *ngFor="let valueType of valueTypeKeys" [value]="valueType">
<mat-icon class="tb-mat-20" svgIcon="{{ valueTypes.get(valueType).icon }}">
</mat-icon>
<span>{{ valueTypes.get(valueType).name | translate }}</span>
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.value</div>
<mat-form-field fxFlex appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex tb-suffix-absolute">
<mat-form-field appearance="outline" subscriptSizing="dynamic" class="tb-inline-field flex flex-1 tb-suffix-absolute">
<ng-container [ngSwitch]="keyControl.get('type').value">
<input *ngSwitchCase="MappingValueType.STRING" matInput required formControlName="string"
placeholder="{{ 'gateway.set' | translate }}" />

View File

@ -18,7 +18,7 @@
<div [formGroup]="connectorForm" class="add-connector">
<mat-toolbar color="primary">
<h2>{{ "gateway.add-connector" | translate}}</h2>
<span fxFlex></span>
<span class="flex-1"></span>
<div [tb-help]="helpLinkId()"></div>
<button mat-icon-button
(click)="cancel()"
@ -27,10 +27,9 @@
</button>
</mat-toolbar>
<div mat-dialog-content>
<div class="tb-form-panel no-border no-padding" fxLayout="column">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-panel no-border no-padding">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.type</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="type">
<mat-option *ngFor="let type of gatewayConnectorDefaultTypesTranslatesMap | keyvalue" [value]="type.key">
@ -38,11 +37,9 @@
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput autocomplete="off" name="value" formControlName="name" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -56,44 +53,37 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div *ngIf="connectorForm.get('type').value === connectorType.CUSTOM" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="connectorForm.get('type').value === connectorType.CUSTOM" class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.connectors-table-class</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="class" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div *ngIf="connectorForm.get('type').value === connectorType.GRPC" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="connectorForm.get('type').value === connectorType.GRPC" class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.connectors-table-key</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="key" placeholder="{{ 'gateway.set' | translate }}"/>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.remote-logging-level</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="logLevel">
<mat-option *ngFor="let logLevel of gatewayLogLevel" [value]="logLevel">{{ logLevel }}</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div *ngIf="connectorForm.get('type').value !== connectorType.GRPC && connectorForm.get('type').value !== connectorType.CUSTOM"
class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="useDefaults">
class="tb-form-row column-xs">
<mat-slide-toggle class="mat-slide" formControlName="useDefaults">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.fill-connector-defaults-hint' | translate }}">
{{ 'gateway.fill-connector-defaults' | translate }}
</mat-label>
</mat-slide-toggle>
</div>
<div *ngIf="connectorForm.get('type').value === connectorType.MQTT" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="sendDataOnlyOnChange">
<div *ngIf="connectorForm.get('type').value === connectorType.MQTT" class="tb-form-row column-xs">
<mat-slide-toggle class="mat-slide" formControlName="sendDataOnlyOnChange">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.send-change-data-hint' | translate }}">
{{ 'gateway.send-change-data' | translate }}
</mat-label>
@ -101,7 +91,7 @@
</div>
</div>
</div>
<div mat-dialog-actions fxLayoutAlign="end center">
<div mat-dialog-actions class="justify-end">
<button mat-button color="primary"
type="button"
cdkFocusInitial

View File

@ -18,7 +18,7 @@
<div [formGroup]="mappingForm" class="key-mapping">
<mat-toolbar color="primary">
<h2>{{ MappingTypeTranslationsMap.get(this.data?.mappingType) | translate}}</h2>
<span fxFlex></span>
<span class="flex-1"></span>
<div [tb-help]="HelpLinkByMappingTypeMap.get(this.data.mappingType)"></div>
<button mat-icon-button
(click)="cancel()"
@ -27,16 +27,15 @@
</button>
</mat-toolbar>
<div mat-dialog-content>
<div class="tb-form-panel no-border no-padding" fxLayout="column">
<div class="tb-form-panel no-border no-padding">
<div class="tb-form-hint tb-primary-fill">
{{ MappingHintTranslationsMap.get(this.data?.mappingType) | translate }}
</div>
<ng-container [ngSwitch]="data.mappingType">
<ng-template [ngSwitchCase]="MappingType.DATA">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.topic-filter</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="topicFilter" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -54,21 +53,18 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.response-topic-Qos-hint' | translate }}">
{{ 'gateway.mqtt-qos' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="subscriptionQos">
<mat-option *ngFor="let type of qualityTypes" [value]="type">
{{ QualityTranslationsMap.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<ng-container formGroupName="converter">
<div class="tb-form-row space-between tb-flex">
@ -142,13 +138,12 @@
</div>
</div>
<div class="tb-form-panel no-border no-padding" *ngIf="converterType === ConvertorTypeEnum.CUSTOM">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required"
tb-hint-tooltip-icon="{{ 'gateway.extension-hint' | translate }}">
{{ 'gateway.extension' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="extension" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -160,7 +155,6 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row space-between same-padding tb-flex column">
<div class="tb-form-panel-title" translate>gateway.extension-configuration</div>
@ -194,27 +188,24 @@
</ng-container>
</ng-template>
<ng-template [ngSwitchCase]="MappingType.REQUESTS">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.request-type</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="requestType">
<mat-option *ngFor="let type of requestTypes" [value]="type">
{{ RequestTypesTranslationsMap.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<ng-container formGroupName="requestValue">
<ng-container [formGroup]="mappingForm.get('requestValue').get(requestMappingType)" [ngSwitch]="requestMappingType">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center"
<div class="tb-form-row column-xs"
*ngIf="requestMappingType === RequestTypeEnum.ATTRIBUTE_REQUEST ||
requestMappingType === RequestTypeEnum.CONNECT_REQUEST ||
requestMappingType === RequestTypeEnum.DISCONNECT_REQUEST">
<div class="fixed-title-width tb-required" translate>gateway.topic-filter</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" [formControl]="mappingForm.get('requestValue').get(requestMappingType).get('topicFilter')"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -233,7 +224,6 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<ng-template [ngSwitchCase]="RequestTypeEnum.CONNECT_REQUEST">
<tb-device-info-table formControlName="deviceInfo" [deviceInfoType]="DeviceInfoType.FULL" required="true">
@ -249,19 +239,19 @@
<div class="tb-form-hint tb-primary-fill" translate>
gateway.from-device-request-settings-hint
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center" formGroupName="deviceInfo">
<div class="tb-form-row column-xs" formGroupName="deviceInfo">
<div class="fixed-title-width tb-flex no-flex align-center" translate>
<div class="tb-required" translate>gateway.device-info.device-name-expression</div>
</div>
<div class="tb-flex">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<div class="flex flex-1">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="deviceNameExpressionSource">
<mat-option *ngFor="let type of sourceTypes" [value]="type">
{{ SourceTypeTranslationsMap.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceNameExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -281,17 +271,17 @@
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.attribute-name-expression</div>
<div class="tb-flex">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<div class="flex flex-1">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="attributeNameExpressionSource">
<mat-option *ngFor="let type of sourceTypes" [value]="type">
{{ SourceTypeTranslationsMap.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="attributeNameExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -317,10 +307,9 @@
<div class="tb-form-hint tb-primary-fill" translate>
gateway.to-device-response-settings-hint
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.response-value-expression</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="valueExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -338,12 +327,10 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.response-topic-expression</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="topicExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -361,9 +348,8 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="retain">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.retain-hint' | translate }}">
{{ 'gateway.retain' | translate }}
@ -373,13 +359,12 @@
</div>
</ng-template>
<ng-template [ngSwitchCase]="RequestTypeEnum.ATTRIBUTE_UPDATE">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required"
tb-hint-tooltip-icon="{{ 'gateway.device-name-filter-hint' | translate }}">
{{ 'gateway.device-name-filter' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceNameFilter" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -391,14 +376,12 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.attribute-filter-hint' | translate }}">
{{ 'gateway.attribute-filter' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="attributeFilter" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -410,12 +393,10 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.response-value-expression</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="valueExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -433,12 +414,10 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.response-topic-expression</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="topicExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -456,10 +435,9 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<mat-slide-toggle class="mat-slide fixed-title-width" formControlName="retain">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="retain">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.retain-hint' | translate }}">
{{ 'gateway.retain' | translate }}
</mat-label>
@ -477,12 +455,11 @@
</tb-toggle-option>
</tb-toggle-select>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.device-name-filter-hint' | translate }}">
{{ 'gateway.device-name-filter' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceNameFilter" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -494,14 +471,12 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" tb-hint-tooltip-icon="{{ 'gateway.method-filter-hint' | translate }}">
{{ 'gateway.method-filter' | translate }}
</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="methodFilter" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -513,12 +488,10 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.request-topic-expression</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="requestTopicExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -536,12 +509,10 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.value-expression</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="valueExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -559,13 +530,11 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<ng-container *ngIf="mappingForm.get('requestValue.serverSideRpc.type').value === ServerSideRPCType.TWO_WAY">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.response-topic-expression</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="responseTopicExpression" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -583,9 +552,8 @@
[tb-help-popup-style]="{maxWidth: '970px'}">
</div>
</mat-form-field>
</div>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" tb-hint-tooltip-icon="{{ 'gateway.response-topic-Qos-hint' | translate }}">
{{ 'gateway.response-topic-Qos' | translate }}
</div>
@ -597,10 +565,9 @@
</mat-select>
</mat-form-field>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.response-timeout</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" type="number" min="1" formControlName="responseTimeout"
placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
@ -614,7 +581,6 @@
warning
</mat-icon>
</mat-form-field>
</div>
</div>
</ng-container>
</ng-template>
@ -622,21 +588,21 @@
</ng-container>
</ng-template>
<ng-template [ngSwitchCase]="MappingType.OPCUA">
<div class="tb-form-row column-xs" fxLayoutAlign="center">
<div class="tb-form-row column-xs">
<div class="tb-flex no-flex align-center" translate>
<div class="tb-required" tb-hint-tooltip-icon="{{ 'gateway.device-node-hint' | translate }}">
{{ 'gateway.device-node' | translate }}
</div>
</div>
<div class="tb-flex device-config">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex" appearance="outline" subscriptSizing="dynamic">
<mat-select formControlName="deviceNodeSource">
<mat-option *ngFor="let type of [OPCUaSourceTypesEnum.PATH, OPCUaSourceTypesEnum.IDENTIFIER]" [value]="type">
{{ SourceTypeTranslationsMap.get(type) | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field class="tb-flex no-gap device-node-pattern-field" appearance="outline" subscriptSizing="dynamic">
<mat-form-field class="tb-flex device-node-pattern-field" appearance="outline" subscriptSizing="dynamic">
<input matInput name="value" formControlName="deviceNodePattern" placeholder="{{ 'gateway.set' | translate }}"/>
<mat-icon matSuffix
matTooltipPosition="above"
@ -750,7 +716,7 @@
</ng-container>
</div>
</div>
<div mat-dialog-actions fxLayoutAlign="end center">
<div mat-dialog-actions class="justify-end">
<button mat-button color="primary"
type="button"
cdkFocusInitial

View File

@ -17,9 +17,8 @@
-->
<div class="connector-container tb-form-panel no-border">
<section class="table-section tb-form-panel no-padding flex section-container">
<mat-toolbar class="mat-mdc-table-toolbar">
<mat-toolbar class="mat-mdc-table-toolbar justify-between">
<h2>{{ 'gateway.connectors' | translate }}</h2>
<span fxFlex></span>
<button *ngIf="dataSource?.data?.length"
mat-icon-button
[disabled]="isLoading$ | async"
@ -30,8 +29,8 @@
</button>
</mat-toolbar>
<div class="table-container">
<section *ngIf="!dataSource?.data?.length" fxLayoutAlign="center center"
class="mat-headline-5 tb-absolute-fill tb-add-new">
<section *ngIf="!dataSource?.data?.length"
class="mat-headline-5 tb-absolute-fill tb-add-new justify-center items-center">
<button mat-button class="connector"
(click)="onAddConnector($event)">
<mat-icon class="tb-mat-96">add</mat-icon>
@ -89,13 +88,12 @@
</mat-cell>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<mat-header-cell *matHeaderCellDef
[ngStyle.gt-md]="{ minWidth: '144px', maxWidth: '144px', width: '144px', textAlign: 'center'}">
{{ 'gateway.connectors-table-actions' | translate }}
<mat-header-cell *matHeaderCellDef>
<div class="gt-md:!hidden" style="width: 48px; min-width: 48px; max-width: 48px;"></div>
<div class="lt-lg:!hidden" [style]="{ minWidth: '144px', maxWidth: '144px', textAlign: 'center'}">{{ 'gateway.connectors-table-actions' | translate }}</div>
</mat-header-cell>
<mat-cell *matCellDef="let attribute"
[ngStyle.gt-md]="{ minWidth: '144px', maxWidth: '144px', width: '144px'}">
<div fxHide fxShow.gt-md fxFlex fxLayout="row" fxLayoutAlign="end">
<mat-cell *matCellDef="let attribute">
<div class="flex-row justify-end lt-md:!hidden" [style]="{ minWidth: '144px', maxWidth: '144px', width: '144px', textAlign: 'center'}">
<button mat-icon-button
matTooltip="RPC"
matTooltipPosition="above"
@ -115,7 +113,7 @@
<mat-icon>delete</mat-icon>
</button>
</div>
<div fxHide fxShow.lt-lg>
<div class="gt-sm:!hidden">
<button mat-icon-button
(click)="$event.stopPropagation()"
[matMenuTriggerFor]="cellActionsMenu">
@ -168,9 +166,8 @@
</tb-toggle-option>
</tb-toggle-select>
</div>
<span [fxShow]="!initialConnector"
fxLayoutAlign="center center"
class="no-data-found" translate>
<span [class.!hidden]="initialConnector"
class="no-data-found justify-center items-center" translate>
gateway.select-connector
</span>
<section class="tb-form-panel section-container no-border no-padding tb-flex space-between" *ngIf="initialConnector">
@ -230,9 +227,7 @@
</mat-tab>
<mat-tab label="{{ 'gateway.configuration' | translate }}*">
<tb-json-object-edit
fillHeight="true"
class="tb-flex fill-height"
fxLayout="column"
[fillHeight]="true"
jsonRequired
label="{{ 'gateway.configuration' | translate }}"
formControlName="configurationJson">
@ -240,7 +235,7 @@
</mat-tab>
</mat-tab-group>
</ng-template>
<div fxLayoutAlign="end center">
<div class="flex justify-end">
<button mat-raised-button color="primary"
type="button"
[disabled]="!connectorForm.dirty || connectorForm.invalid"
@ -253,7 +248,7 @@
</div>
<ng-template #generalTabContent>
<section [formGroup]="connectorForm" class="tb-form-panel no-border no-padding padding-top section-container flex">
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center" >
<div class="tb-form-row column-xs">
<div class="fixed-title-width tb-required" translate>gateway.name</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
@ -271,7 +266,7 @@
</mat-form-field>
</div>
</div>
<div *ngIf="connectorForm.get('type').value === ConnectorType.CUSTOM" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="connectorForm.get('type').value === ConnectorType.CUSTOM" class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.connectors-table-class</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
@ -279,7 +274,7 @@
</mat-form-field>
</div>
</div>
<div *ngIf="connectorForm.get('type').value === ConnectorType.GRPC" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="connectorForm.get('type').value === ConnectorType.GRPC" class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.connectors-table-key</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
@ -289,14 +284,14 @@
</div>
<div class="tb-form-panel stroked">
<div class="tb-form-panel-title" translate>gateway.logs-configuration</div>
<div class="tb-form-row" fxLayoutAlign="space-between center">
<div class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="enableRemoteLogging">
<mat-label>
{{ 'gateway.enable-remote-logging' | translate }}
</mat-label>
</mat-slide-toggle>
</div>
<div class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div class="tb-form-row column-xs">
<div class="fixed-title-width" translate>gateway.remote-logging-level</div>
<div class="tb-flex no-gap">
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic">
@ -307,7 +302,7 @@
</div>
</div>
</div>
<div *ngIf="connectorForm.get('type').value === ConnectorType.MQTT" class="tb-form-row column-xs" fxLayoutAlign="space-between center">
<div *ngIf="connectorForm.get('type').value === ConnectorType.MQTT" class="tb-form-row">
<mat-slide-toggle class="mat-slide" formControlName="sendDataOnlyOnChange">
<mat-label tb-hint-tooltip-icon="{{ 'gateway.send-change-data-hint' | translate }}">
{{ 'gateway.send-change-data' | translate }}

View File

@ -35,25 +35,27 @@
required
>
</tb-entity-gateway-select>
<div fxLayout="column">
<mat-form-field fxFlex>
<mat-label>{{'gateway.security-type' | translate }}</mat-label>
<mat-select formControlName="securityType" >
<mat-option *ngFor="let securityType of securityTypes | keyvalue" [value]="securityType.key">
{{ securityType.value.toString() | translate }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div [fxLayout]="alignment" [fxLayoutGap]="layoutGap">
<mat-form-field fxFlex>
<mat-form-field class="flex">
<mat-label>{{'gateway.security-type' | translate }}</mat-label>
<mat-select formControlName="securityType" >
<mat-option *ngFor="let securityType of securityTypes | keyvalue" [value]="securityType.key">
{{ securityType.value.toString() | translate }}
</mat-option>
</mat-select>
</mat-form-field>
<div class="flex" [class]="{
'gap-1.25': layoutGap,
'flex-row': alignment,
'flex-col': !alignment
}">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.thingsboard-host' | translate }}</mat-label>
<input matInput type="text" formControlName="host">
<mat-error *ngIf="gatewayConfigurationGroup.get('host').hasError('required')" translate>
gateway.thingsboard-host-required
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.thingsboard-port' | translate }}</mat-label>
<input matInput type="number" formControlName="port">
<mat-error *ngIf="gatewayConfigurationGroup.get('port').hasError('required')" translate>
@ -71,16 +73,16 @@
</mat-form-field>
</div>
<div *ngIf="gatewayConfigurationGroup.get('securityType').value == 'tls'" fxLayout="column">
<mat-form-field fxFlex>
<div *ngIf="gatewayConfigurationGroup.get('securityType').value == 'tls'" class="flex flex-col">
<mat-form-field>
<mat-label>{{ 'gateway.tls-path-ca-certificate' | translate }}</mat-label>
<input matInput type="text" formControlName="caCertPath">
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field>
<mat-label>{{ 'gateway.tls-path-private-key' | translate }}</mat-label>
<input matInput type="text" formControlName="privateKeyPath">
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field>
<mat-label>{{ 'gateway.tls-path-client-certificate' | translate }}</mat-label>
<input matInput type="text" formControlName="certPath">
</mat-form-field>
@ -88,8 +90,12 @@
<mat-checkbox formControlName="remoteConfiguration">{{ 'gateway.remote' | translate }}</mat-checkbox>
<div [fxLayout]="alignment" [fxLayoutGap]="layoutGap">
<mat-form-field fxFlex>
<div class="flex" [class]="{
'gap-1.25': layoutGap,
'flex-row': alignment,
'flex-col': !alignment
}">
<mat-form-field class="flex-1">
<mat-label>{{'gateway.remote-logging-level' | translate }}</mat-label>
<mat-select formControlName="remoteLoggingLevel">
<mat-option *ngFor="let logLevel of gatewayLogLevels" [value]="logLevel">
@ -98,7 +104,7 @@
</mat-select>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.path-logs' | translate }}</mat-label>
<input matInput type="text" formControlName="remoteLoggingPathToLogs">
<mat-error *ngIf="gatewayConfigurationGroup.get('remoteLoggingPathToLogs').hasError('required')" translate>
@ -116,8 +122,8 @@
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column">
<mat-form-field fxFlex>
<div class="flex flex-col">
<mat-form-field>
<mat-label>{{'gateway.storage-type' | translate }}</mat-label>
<mat-select formControlName="storageType">
<mat-option *ngFor="let storageType of storageTypes | keyvalue" [value]="storageType.key">
@ -126,8 +132,12 @@
</mat-select>
</mat-form-field>
<div [fxLayout]="alignment" [fxLayoutGap]="layoutGap">
<mat-form-field fxFlex>
<div class="flex" [class]="{
'gap-1.25': layoutGap,
'flex-row': alignment,
'flex-col': !alignment
}">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.storage-pack-size' | translate }}</mat-label>
<input matInput type="number" formControlName="readRecordsCount">
<mat-error *ngIf="gatewayConfigurationGroup.get('readRecordsCount').hasError('required')" translate>
@ -141,7 +151,7 @@
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label >
{{ (gatewayConfigurationGroup.get('storageType').value !== 'file' ? 'gateway.storage-max-records' : 'gateway.storage-max-file-records') | translate}}
</mat-label>
@ -158,8 +168,12 @@
</mat-form-field>
</div>
<div [fxLayout]="alignment" [fxLayoutGap]="layoutGap" *ngIf="gatewayConfigurationGroup.get('storageType').value == 'file'">
<mat-form-field fxFlex>
<div class="flex" [class]="{
'gap-1.25': layoutGap,
'flex-row': alignment,
'flex-col': !alignment
}" *ngIf="gatewayConfigurationGroup.get('storageType').value == 'file'">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.storage-max-files' | translate }}</mat-label>
<input matInput type="number" formControlName="maxFilesCount">
<mat-error *ngIf="gatewayConfigurationGroup.get('maxFilesCount').hasError('required')" translate>
@ -173,7 +187,7 @@
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.storage-path' | translate }}</mat-label>
<input matInput type="text" formControlName="dataFolderPath">
<mat-error *ngIf="gatewayConfigurationGroup.get('dataFolderPath').hasError('required')" translate>
@ -191,14 +205,18 @@
</mat-panel-title>
</mat-expansion-panel-header>
<div fxLayout="column" class="gateway-config">
<div class="flex flex-col gateway-config">
<section formArrayName="connectors" *ngFor="let connector of connectors.controls; let i = index;">
<div [formGroupName]="i" fxLayout="row" fxLayoutAlign="space-between stretch" fxLayoutGap="8px">
<div fxLayout="column" fxLayoutAlign="center start">
<div [formGroupName]="i" class="flex flex-row justify-between items-stretch gap-2">
<div class="flex flex-col justify-center">
<mat-slide-toggle formControlName="enabled"></mat-slide-toggle>
</div>
<div [fxLayout]="alignment" [fxLayoutGap]="layoutGap" fxFlex>
<mat-form-field fxFlex>
<div class="flex flex-full" [class]="{
'gap-1.25': layoutGap,
'flex-row': alignment,
'flex-col': !alignment
}">
<mat-form-field class="flex-1">
<mat-label>{{'gateway.connector-type' | translate }}</mat-label>
<mat-select formControlName="configType" (selectionChange)="changeConnectorType(connector)">
<mat-option *ngFor="let connectorType of connectorTypes" [value]="connectorType">
@ -210,7 +228,7 @@
</mat-error>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.connector-name' | translate }}</mat-label>
<input matInput type="text" formControlName="name" (blur)="changeConnectorName(connector, i)">
<mat-error *ngIf="connector.get('name').hasError('required')" translate>
@ -218,12 +236,15 @@
</mat-error>
</mat-form-field>
</div>
<div [fxLayout]="alignment" [fxLayoutGap]="layoutGap"
fxLayoutAlign="{{alignment == 'row' ? 'end center' : 'space-evenly center'}}" class="action-buttons">
<div class="flex action-buttons" [class]="{
'gap-1.25': layoutGap,
'flex-row justify-end item-center': alignment,
'flex-col justify-evenly item-center': !alignment
}">
<button [disabled]="isReadOnlyForm" mat-icon-button (click)="openConfigDialog($event, i, connector.get('config').value, connector.get('name').value)"
matTooltip="{{ 'gateway.update-config' | translate }}"
matTooltipPosition="above"
[ngClass]="{'mat-warn': connector.get('config').invalid}">
[class.mat-warn]="connector.get('config').invalid">
<mat-icon>more_horiz</mat-icon>
</button>
<button [disabled]="isReadOnlyForm"
@ -235,9 +256,9 @@
</div>
</div>
</section>
<span [fxShow]="!connectors.length" fxLayoutAlign="center center" class="no-data-found">{{'gateway.no-connectors' | translate}}</span>
<span [class.!hidden]="connectors.length" class="no-data-found justify-center items-center">{{'gateway.no-connectors' | translate}}</span>
<div>
<button [fxShow]="!isReadOnlyForm" mat-raised-button type="button" (click)="addNewConnector()"
<button [class.!hidden]="isReadOnlyForm" mat-raised-button type="button" (click)="addNewConnector()"
matTooltip="{{ 'gateway.connector-add' | translate }}"
matTooltipPosition="above">
{{ 'action.add' | translate }}
@ -246,8 +267,7 @@
</div >
</mat-expansion-panel>
</mat-accordion>
<section [fxShow]="!isReadOnlyForm"
fxLayout="row" fxLayoutAlign="end center" class="form-action-buttons">
<section [class.!hidden]="isReadOnlyForm" class="flex flex-row justify-end items-center form-action-buttons">
<button mat-raised-button color="primary" type="button"
(click)="exportConfig()"
*ngIf="!gatewayConfigurationGroup.get('remoteConfiguration').value"

View File

@ -97,8 +97,8 @@ export class GatewayFormComponent extends PageComponent implements OnInit, OnDes
private subscribeStorageType$: any;
private subscribeGateway$: any;
alignment = 'row';
layoutGap = '5px';
alignment = true;
layoutGap = true;
gatewayType: string;
gatewayConfigurationGroup: UntypedFormGroup;
securityTypes = SecurityTypeTranslationMap;
@ -166,11 +166,11 @@ export class GatewayFormComponent extends PageComponent implements OnInit, OnDes
private updateWidgetDisplaying(): void {
if(this.ctx.$container && this.ctx.$container[0].offsetWidth <= 425){
this.layoutGap = '0';
this.alignment = 'column';
this.layoutGap = false;
this.alignment = false;
} else {
this.layoutGap = '5px';
this.alignment = 'row';
this.layoutGap = true;
this.alignment = true;
}
}

View File

@ -45,10 +45,9 @@
<mat-header-row class="mat-row-select" *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
<mat-row class="mat-row-select" *matRowDef="let attribute; columns: displayedColumns;"></mat-row>
</table>
<span [fxShow]="dataSource.data.length === 0"
fxFlex fxLayoutAlign="center center"
class="no-data-found">{{ 'attribute.no-telemetry-text' | translate }}</span>
<span fxFlex [fxShow]="dataSource.data.length !== 0"></span>
<span [class.!hidden]="dataSource.data.length !== 0"
class="flex-1 justify-center items-center no-data-found">{{ 'attribute.no-telemetry-text' | translate }}</span>
<span class="flex-1" [class.!hidden]="dataSource.data.length === 0"></span>
<mat-divider></mat-divider>
<mat-paginator [length]="dataSource.data.length"
[pageIndex]="pageLink.page"

View File

@ -18,14 +18,14 @@
<mat-toolbar color="warn">
<mat-icon>warning</mat-icon>
<h2 translate>gateway.configuration-delete-dialog-header</h2>
<span fxFlex></span>
<span class="flex-1"></span>
<button mat-icon-button
(click)="close()"
type="button">
<mat-icon class="material-icons">close</mat-icon>
</button>
</mat-toolbar>
<div mat-dialog-content style="max-width: 600px" class="mat-content" fxLayout="column">
<div mat-dialog-content style="max-width: 600px" class="mat-content flex-col">
<span innerHTML="{{ 'gateway.configuration-delete-dialog-body' | translate }} <b>{{ gatewayName }}</b>" ></span>
<mat-form-field class="mat-block tb-value-type" style="flex-grow: 0">
<mat-label translate>gateway.configuration-delete-dialog-input</mat-label>
@ -36,7 +36,7 @@
</mat-error>
</mat-form-field>
</div>
<div mat-dialog-actions fxLayoutAlign="end center">
<div mat-dialog-actions class="justify-end">
<button mat-button color="warn"
type="button"
cdkFocusInitial

View File

@ -15,16 +15,15 @@
limitations under the License.
-->
<mat-toolbar color="primary">
<mat-toolbar color="primary" class="justify-between">
<h2 translate>gateway.rpc.save-template</h2>
<span fxFlex></span>
<button mat-icon-button
(click)="close()"
type="button">
<mat-icon class="material-icons">close</mat-icon>
</button>
</mat-toolbar>
<div mat-dialog-content style="width: 600px" class="mat-content" fxLayout="column">
<div mat-dialog-content style="width: 600px" class="mat-content flex flex-col">
<mat-form-field class="mat-block tb-value-type" style="flex-grow: 0">
<mat-label translate>gateway.rpc.template-name</mat-label>
<input matInput [formControl]="templateNameCtrl" required/>
@ -39,7 +38,7 @@
{{ 'gateway.rpc.template-name-duplicate' | translate }}
</div>
</div>
<div mat-dialog-actions fxLayoutAlign="end center">
<div mat-dialog-actions class="justify-end">
<button mat-button
type="button"
(click)="close()">

View File

@ -37,10 +37,11 @@
[ngTemplateOutletContext]="{ $implicit: config, innerValue: false }">
</ng-container>
<ng-template #RPCTemplateRef let-config let-innerValue='innerValue'>
<div [fxLayout]="isObject(config.value) ? 'column': 'row'"
[fxLayoutAlign]="!isObject(config.value) ? 'space-between center' : ''"
[ngStyle]="{'padding-left': innerValue ? '16px': '0'}"
class="rpc-params-row">
<div [class]="{
'flex-col': isObject(config.value),
'flex-row justify-between items-center': !isObject(config.value),
}" [style]="{'padding-left': innerValue ? '16px': '0'}"
class="rpc-params-row flex">
<div class="template-key">
{{!innerValue ? ('gateway.rpc.' + config.key | translate) : config.key}}
</div>
@ -49,7 +50,7 @@
</div>
<ng-container *ngIf="isObject(config.value)" [ngTemplateOutlet]="RPCObjectRow"></ng-container>
<div *ngIf="!isObject(config.value) && !isArray(config.value)"
[ngClass]="{'boolean-true': config.value === true,
[class]="{'boolean-true': config.value === true,
'boolean-false': config.value === false }">
<ng-container *ngIf="config.key === 'method' else value" [ngTemplateOutlet]="SNMPMethod"></ng-container>
</div>

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<div fxLayout="column" class="command-form" [formGroup]="commandForm">
<div class="command-form flex flex-col" [formGroup]="commandForm">
<div
class="mat-subtitle-1 title">{{ 'gateway.rpc.title' | translate: {type: gatewayConnectorDefaultTypesTranslates.get(connectorType)} }}</div>
<ng-template [ngIf]="connectorType">
@ -38,8 +38,8 @@
<input matInput formControlName="requestTimeout" type="number"
min="10" step="1" placeholder="1000"/>
</mat-form-field>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field fxFlex="50" class="mat-block">
<div class="flex flex-1 flex-row gap-2.5">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.objectType' | translate }}</mat-label>
<mat-select formControlName="objectType">
<mat-option *ngFor="let type of bACnetObjectTypes" [value]="type">
@ -47,7 +47,7 @@
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="50">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.identifier' | translate }}</mat-label>
<input matInput formControlName="identifier" type="number"
min="1" step="1" placeholder="1"/>
@ -97,12 +97,12 @@
<mat-slide-toggle class="mat-slide margin" formControlName="bitrateSwitch">
{{ 'gateway.rpc.bitrateSwitch' | translate }}
</mat-slide-toggle>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field fxFlex="50">
<div class="flex flex-1 flex-row gap-2.5">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.dataLength' | translate }}</mat-label>
<input matInput formControlName="dataLength" type="number" placeholder="2" min="1" step="1"/>
</mat-form-field>
<mat-form-field class="mat-block" fxFlex="50">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.dataByteorder' | translate }}</mat-label>
<mat-select formControlName="dataByteorder">
<mat-option *ngFor="let order of cANByteOrders" [value]="order">
@ -111,12 +111,12 @@
</mat-select>
</mat-form-field>
</div>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field fxFlex="50">
<div class="flex flex-1 flex-row gap-2.5">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.dataBefore' | translate }}</mat-label>
<input matInput formControlName="dataBefore" placeholder="00AA"/>
</mat-form-field>
<mat-form-field fxFlex="50">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.dataAfter' | translate }}</mat-label>
<input matInput formControlName="dataAfter" placeholder="0102"/>
</mat-form-field>
@ -205,21 +205,21 @@
<mat-slide-toggle class="mat-slide margin" formControlName="withResponse">
{{ 'gateway.rpc.withResponse' | translate }}
</mat-slide-toggle>
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="oid">
<fieldset class="fields border flex flex-col gap-2.5" formArrayName="oid">
<span class="fields-label">{{ 'gateway.rpc.oids' | translate }}*</span>
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"
<div class="flex flex-1 flex-row justify-center items-center gap-2.5"
*ngFor="let control of getFormArrayControls('oid'); let i = index">
<mat-form-field class="tb-inline-field" appearance="outline" fxFlex subscriptSizing="dynamic">
<mat-form-field class="tb-inline-field flex-1" appearance="outline" subscriptSizing="dynamic">
<input matInput [formControl]="control" required/>
</mat-form-field>
<mat-icon style="cursor:pointer;"
fxFlex="30px"
<mat-icon style="cursor:pointer; max-width:30px;min-width:30px"
class="flex-[1_1_30px]"
(click)="removeSNMPoid(i)"
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete
</mat-icon>
</div>
<button mat-raised-button
fxFlexAlign="start"
class="self-start"
(click)="addSNMPoid()">
{{ 'gateway.rpc.add-oid' | translate }}
</button>
@ -230,8 +230,8 @@
<mat-label>{{ 'gateway.rpc.methodFilter' | translate }}</mat-label>
<input matInput formControlName="methodFilter" placeholder="post_attributes"/>
</mat-form-field>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field class="mat-block" fxFlex="33">
<div class="flex flex-1 flex-row gap-2.5">
<mat-form-field class="flex-[1_1_33%] max-w-4/12">
<mat-label>{{ 'gateway.rpc.httpMethod' | translate }}</mat-label>
<mat-select formControlName="httpMethod">
<mat-option *ngFor="let method of hTTPMethods" [value]="method">
@ -239,24 +239,24 @@
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.requestUrlExpression' | translate }}</mat-label>
<input matInput formControlName="requestUrlExpression"
placeholder="http://127.0.0.1:5000/my_devices"/>
</mat-form-field>
</div>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field fxFlex="33">
<div class="flex flex-1 flex-row gap-2.5">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.responseTimeout' | translate }}</mat-label>
<input matInput formControlName="responseTimeout" type="number"
step="1" min="10" placeholder="10"/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.timeout' | translate }}</mat-label>
<input matInput formControlName="timeout" type="number"
step="1" min="10" placeholder="1000"/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.tries' | translate }}</mat-label>
<input matInput formControlName="tries" type="number"
step="1" min="1" placeholder="3"/>
@ -266,26 +266,25 @@
<mat-label>{{ 'gateway.rpc.valueExpression' | translate }}</mat-label>
<input matInput formControlName="valueExpression" placeholder="${params}"/>
</mat-form-field>
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders">
<fieldset class="fields border flex flex-col gap-2.5" formArrayName="httpHeaders">
<span class="fields-label">{{ 'gateway.rpc.httpHeaders' | translate }}</span>
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length">
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center">
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span>
<span fxFlex class="title">{{ 'gateway.rpc.value' | translate }}</span>
<span fxFlex="30px"></span>
<div class="border flex flex-col gap-2.5" *ngIf="getFormArrayControls('httpHeaders').length">
<div class="flex flex-row justify-center items-center gap-2.5">
<span class="title flex-1">{{ 'gateway.rpc.header-name' | translate }}</span>
<span class="title flex-1">{{ 'gateway.rpc.value' | translate }}</span>
<span style="width: 30px"></span>
</div>
<mat-divider></mat-divider>
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"
<div class="flex flex-row justify-center items-center gap-2.5"
*ngFor="let control of getFormArrayControls('httpHeaders'); let i = index">
<ng-container [formGroupName]="i">
<mat-form-field appearance="outline" fxFlex>
<mat-form-field appearance="outline" class="flex-1">
<input matInput formControlName="headerName"/>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex>
<mat-form-field appearance="outline" class="flex-1">
<input matInput formControlName="value" placeholder="application/json"/>
</mat-form-field>
<mat-icon style="cursor:pointer;"
fxFlex="30px"
<mat-icon style="cursor:pointer; width: 30px"
(click)="removeHTTPHeader(i)"
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete
</mat-icon>
@ -293,7 +292,7 @@
</div>
</div>
<button mat-raised-button
fxFlexAlign="start"
class="self-start"
(click)="addHTTPHeader()">
{{ 'gateway.rpc.add-header' | translate }}
</button>
@ -305,8 +304,8 @@
<mat-label>{{ 'gateway.rpc.methodFilter' | translate }}</mat-label>
<input matInput formControlName="methodFilter" placeholder="echo"/>
</mat-form-field>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field class="mat-block" fxFlex="33">
<div class="flex flex-row justify-center items-center gap-2.5">
<mat-form-field class="flex-[1_1_33%] max-w-4/12">
<mat-label>{{ 'gateway.rpc.httpMethod' | translate }}</mat-label>
<mat-select formControlName="httpMethod">
<mat-option *ngFor="let method of hTTPMethods" [value]="method">
@ -314,23 +313,23 @@
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.requestUrlExpression' | translate }}</mat-label>
<input matInput formControlName="requestUrlExpression" placeholder="http://127.0.0.1:5000/my_devices"/>
</mat-form-field>
</div>
<div fxFlex fxLayout="row" fxLayoutGap="10px">
<mat-form-field fxFlex="33">
<div class="flex flex-row justify-center items-center gap-2.5">
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.responseTimeout' | translate }}</mat-label>
<input matInput formControlName="responseTimeout" type="number"
step="1" min="10" placeholder="10"/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.timeout' | translate }}</mat-label>
<input matInput formControlName="timeout" type="number"
step="1" min="10" placeholder="10"/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.rpc.tries' | translate }}</mat-label>
<input matInput formControlName="tries" type="number"
step="1" min="1" placeholder="1"/>
@ -344,26 +343,25 @@
<mat-label>{{ 'gateway.rpc.responseValueExpression' | translate }}</mat-label>
<input matInput formControlName="responseValueExpression" placeholder="${temp}"/>
</mat-form-field>
<fieldset class="fields border" fxLayout="column" fxLayoutGap="10px" formArrayName="httpHeaders">
<fieldset class="fields border flex flex-col gap-2.5" formArrayName="httpHeaders">
<span class="fields-label">{{ 'gateway.rpc.httpHeaders' | translate }}</span>
<div class="border" fxLayout="column" fxLayoutGap="10px" *ngIf="getFormArrayControls('httpHeaders').length">
<div fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center">
<span fxFlex class="title">{{ 'gateway.rpc.header-name' | translate }}</span>
<span fxFlex class="title">{{ 'gateway.rpc.value' | translate }}</span>
<span fxFlex="30px"></span>
<div class="border flex flex-col gap-2.5" *ngIf="getFormArrayControls('httpHeaders').length">
<div class="flex flex-row justify-center items-center gap-2.5">
<span class="title flex-1">{{ 'gateway.rpc.header-name' | translate }}</span>
<span class="title flex-1">{{ 'gateway.rpc.value' | translate }}</span>
<span style="width: 30px"></span>
</div>
<mat-divider></mat-divider>
<div fxFlex fxLayout="row" fxLayoutGap="10px" fxLayoutAlign="center center"
<div class="flex flex-row justify-center items-center gap-2.5"
*ngFor="let control of getFormArrayControls('httpHeaders'); let i = index">
<ng-container [formGroupName]="i">
<mat-form-field appearance="outline" fxFlex>
<mat-form-field appearance="outline" class="flex-1">
<input matInput formControlName="headerName" placeholder="{{ 'gateway.rpc.set' | translate }}"/>
</mat-form-field>
<mat-form-field appearance="outline" fxFlex>
<mat-form-field appearance="outline" class="flex-1">
<input matInput formControlName="value"/>
</mat-form-field>
<mat-icon style="cursor:pointer;"
fxFlex="30px"
<mat-icon style="cursor:pointer;width:30px"
(click)="removeHTTPHeader(i)"
matTooltip="{{ 'gateway.rpc.remove' | translate }}">delete
</mat-icon>
@ -371,7 +369,7 @@
</div>
</div>
<button mat-raised-button
fxFlexAlign="start"
class="self-start"
(click)="addHTTPHeader()">
{{ 'gateway.rpc.add-header' | translate }}
</button>
@ -382,7 +380,7 @@
<mat-label>{{ 'gateway.statistics.command' | translate }}</mat-label>
<input matInput formControlName="command"/>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field>
<mat-label>{{ 'widget-config.datasource-parameters' | translate }}</mat-label>
<input matInput formControlName="params" type="JSON" tb-json-to-string/>
<mat-icon class="material-icons-outlined" aria-hidden="false" aria-label="help-icon"
@ -397,7 +395,7 @@
</ng-template>
</ng-container>
</ng-template>
<div class="template-actions" fxFlex fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px">
<div class="template-actions flex flex-row justify-end gap-2.5">
<button mat-raised-button
(click)="save()"
[disabled]="commandForm.invalid">

View File

@ -15,8 +15,8 @@
limitations under the License.
-->
<div fxLayout="column" fxFlex [ngClass]="{'border': isConnector}">
<div fxLayout="row" fxLayout.lt-sm="column" class="command-form" fxLayoutGap="10px" [formGroup]="commandForm">
<div class="flex flex-1 flex-col" [class]="{'border': isConnector}">
<div class="command-form flex flex-row lt-sm:flex-col gap-2.5" [formGroup]="commandForm">
<ng-container *ngIf="!isConnector; else connectorForm">
<mat-form-field>
<mat-label>{{ 'gateway.statistics.command' | translate }}</mat-label>
@ -26,7 +26,7 @@
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex>
<mat-form-field class="flex-1">
<mat-label>{{ 'gateway.statistics.timeout-ms' | translate }}</mat-label>
<input matInput formControlName="time" type="number" min="1"/>
<mat-error *ngIf="commandForm.get('time').hasError('min')">
@ -49,14 +49,14 @@
(saveTemplate)="saveTemplate()"
/>
<ng-template #updatedParameters>
<div fxLayout="column" class="rpc-parameters">
<div class="flex flex-col rpc-parameters">
<div class="mat-subtitle-1 tb-form-panel-title">{{ 'gateway.rpc.title' | translate: {type: gatewayConnectorDefaultTypesTranslates.get(connectorType)} }}</div>
<ng-container [ngSwitch]="connectorType">
<tb-modbus-rpc-parameters *ngSwitchCase="ConnectorType.MODBUS" formControlName="params"/>
<tb-mqtt-rpc-parameters *ngSwitchCase="ConnectorType.MQTT" formControlName="params"/>
<tb-opc-rpc-parameters *ngSwitchCase="ConnectorType.OPCUA" formControlName="params"/>
</ng-container>
<div class="template-actions" fxFlex fxLayout="row" fxLayoutAlign="end center" fxLayoutGap="10px">
<div class="flex flex-1 fex-row justify-end items-center template-actions gap-2.5">
<button mat-raised-button
(click)="saveTemplate()"
[disabled]="commandForm.get('params').invalid">
@ -75,7 +75,7 @@
</div>
<section class="result-block" [formGroup]="commandForm">
<span>{{ 'gateway.rpc-command-result' | translate }}
<div *ngIf="resultTime" class="result-time" fxFlex fxLayout="row" fxLayoutAlign="center center">
<div *ngIf="resultTime" class="flex flex-1 flex-row justify-center items-center result-time">
<mat-icon class="material-icons">schedule</mat-icon>
<span>{{ resultTime | date: 'yyyy/MM/dd HH:mm:ss' }}</span>
</div>
@ -83,6 +83,6 @@
<tb-json-content [contentType]="contentTypes.JSON" readonly="true" formControlName="result"></tb-json-content>
</section>
</div>
<tb-gateway-service-rpc-connector-templates fxFlex="30" *ngIf="isConnector" class="border" [rpcTemplates]="templates"
<tb-gateway-service-rpc-connector-templates *ngIf="isConnector" class="border" [rpcTemplates]="templates"
[ctx]="ctx" [connectorType]="connectorType" (useTemplate)="useTemplate($event)">
</tb-gateway-service-rpc-connector-templates>

View File

@ -30,6 +30,11 @@
margin-left: 10px;
}
tb-gateway-service-rpc-connector-templates {
flex: 1 1 30%;
max-width: 30%;
}
.command-form {
flex-wrap: nowrap;
@ -83,5 +88,6 @@
box-shadow: 0 0 0 0 rgb(0 0 0 / 20%), 0 0 0 0 rgb(0 0 0 / 14%), 0 0 0 0 rgb(0 0 0 / 12%);
border: solid 1px #e0e0e0;
border-radius: 4px;
}
}

View File

@ -15,7 +15,7 @@
limitations under the License.
-->
<div class="statistics-container" fxLayout="row" fxLayout.lt-md="column">
<div class="statistics-container flex flex-row lt-md:flex-col">
<mat-card [formGroup]="statisticForm" *ngIf="!general">
<mat-form-field class="mat-block" subscriptSizing="dynamic">
<mat-label>{{ 'gateway.statistics.statistic' | translate }}</mat-label>
@ -42,9 +42,9 @@
<input matInput [value]="commandObj.command" disabled>
</mat-form-field>
</mat-card>
<div class="chart-box" fxLayout="column">
<div class="chart-container" #statisticChart [fxShow]="isNumericData"></div>
<table [fxShow]="!isNumericData" mat-table [dataSource]="dataSource"
<div class="chart-box flex flex-col">
<div class="chart-container" #statisticChart [class.!hidden]="!isNumericData" ></div>
<table [class.!hidden]="isNumericData" mat-table [dataSource]="dataSource"
matSort [matSortActive]="pageLink.sortOrder.property" [matSortDirection]="pageLink.sortDirection()"
matSortDisableClear>
<ng-container matColumnDef="0">
@ -67,12 +67,10 @@
<mat-row class="mat-row-select"
*matRowDef="let row; columns: displayedColumns;"></mat-row>
</table>
<span [fxShow]="dataSource.data.length === 0 && !isNumericData"
fxLayoutAlign="center center"
class="no-data-found">{{ 'attribute.no-telemetry-text' | translate }}</span>
<div fxFlex class="legend" fxLayout="row" fxLayoutAlign="center center" [fxShow]="isNumericData">
<div class="legend-keys" *ngFor="let legendKey of legendData?.keys" fxLayout="row"
fxLayoutAlign="center center">
<span [class.!hidden]="dataSource.data.length !== 0 || isNumericData"
class="no-data-found justify-center items-start">{{ 'attribute.no-telemetry-text' | translate }}</span>
<div class="legend flex flex-1 flex-row justify-center items-center" [class.!hidden]="!isNumericData">
<div class="legend-keys flex flex-row justify-center items-center" *ngFor="let legendKey of legendData?.keys">
<span class="legend-line" [style.background-color]="legendKey.dataKey.color"></span>
<div class="legend-label"
(click)="onLegendKeyHiddenChange(legendKey.dataIndex)"

View File

@ -84,7 +84,8 @@ module.exports = {
full: '1 1 100%'
},
gap: {
'0.75': '0.1875rem'
'0.75': '0.1875rem',
'1.25': '0.3125rem'
},
minWidth: {
'25': '6.25rem',