Merge pull request #11758 from maxunbearable/fix/3912-device-table
Gateway fixes
This commit is contained in:
		
						commit
						64bf118b85
					
				@ -2159,17 +2159,17 @@
 | 
			
		||||
              }
 | 
			
		||||
            },
 | 
			
		||||
            {
 | 
			
		||||
              "type": "entity",
 | 
			
		||||
              "type": "entityCount",
 | 
			
		||||
              "entityAliasId": "a75d9031-ba51-8da4-81be-de65061b72f4",
 | 
			
		||||
              "filterId": "44038462-1bae-e075-7b31-283341cb2295",
 | 
			
		||||
              "dataKeys": [
 | 
			
		||||
                {
 | 
			
		||||
                  "name": "count",
 | 
			
		||||
                  "type": "entityField",
 | 
			
		||||
                  "type": "count",
 | 
			
		||||
                  "label": "modbusCount",
 | 
			
		||||
                  "color": "#4caf50",
 | 
			
		||||
                  "color": "#ff5722",
 | 
			
		||||
                  "settings": {},
 | 
			
		||||
                  "_hash": 0.9300660062254784,
 | 
			
		||||
                  "_hash": 0.46402083951505624,
 | 
			
		||||
                  "aggregationType": null,
 | 
			
		||||
                  "units": null,
 | 
			
		||||
                  "decimals": null,
 | 
			
		||||
@ -2192,7 +2192,7 @@
 | 
			
		||||
                {
 | 
			
		||||
                  "name": "count",
 | 
			
		||||
                  "type": "count",
 | 
			
		||||
                  "label": "grcpCount",
 | 
			
		||||
                  "label": "grpcCount",
 | 
			
		||||
                  "color": "#f44336",
 | 
			
		||||
                  "settings": {},
 | 
			
		||||
                  "_hash": 0.16110429492126088,
 | 
			
		||||
@ -2605,9 +2605,9 @@
 | 
			
		||||
          "padding": "0px",
 | 
			
		||||
          "settings": {
 | 
			
		||||
            "useMarkdownTextFunction": false,
 | 
			
		||||
            "markdownTextPattern": "<div style=\"width: 100%; height: 100%; padding: 0;\" fxFlex fxLayout=\"column\">\r\n  <mat-tab-group [(selectedIndex)]=\"selectedTabIndex\">\r\n    <mat-tab label=\"All\" value=\"gateway_devices_0\"></mat-tab>\r\n    <mat-tab *ngIf=\"${mqttCount}\" label=\"MQTT\" value=\"gateway_devices_1\"></mat-tab>\r\n    <mat-tab *ngIf=\"${modbusCount}\" label=\"MODBUS\" value=\"gateway_devices_2\"></mat-tab>\r\n    <mat-tab *ngIf=\"${grpcCount}\" label=\"GRPC\" value=\"gateway_devices_3\"></mat-tab>\r\n    <mat-tab *ngIf=\"${opcuaCount}\" label=\"OPCUA\" value=\"gateway_devices_4\"> </mat-tab>\r\n    <mat-tab *ngIf=\"${bleCount}\" label=\"BLE\" value=\"gateway_devices_6\"></mat-tab>\r\n    <mat-tab *ngIf=\"${requestCount}\" label=\"REQUEST\" value=\"gateway_devices_7\"></mat-tab>\r\n    <mat-tab *ngIf=\"${canCount}\" label=\"CAN\" value=\"gateway_devices_8\"></mat-tab>\r\n    <mat-tab *ngIf=\"${bacnetCount}\" label=\"BACNET\" value=\"gateway_devices_9\"></mat-tab>\r\n    <mat-tab *ngIf=\"${odbcCount}\" label=\"ODBC\" value=\"gateway_devices_10\"></mat-tab>\r\n    <mat-tab *ngIf=\"${restCount}\" label=\"REST\" value=\"gateway_devices_11\"></mat-tab>\r\n    <mat-tab *ngIf=\"${snmpCount}\" label=\"SNMP\" value=\"gateway_devices_12\"></mat-tab>\r\n    <mat-tab *ngIf=\"${ftpCount}\" label=\"FTP\" value=\"gateway_devices_13\"></mat-tab>\r\n    <mat-tab *ngIf=\"${socketCount}\" label=\"SOCKET\" value=\"gateway_devices_14\"></mat-tab>\r\n    <mat-tab *ngIf=\"${xmppCount}\" label=\"XMPP\" value=\"gateway_devices_15\"></mat-tab>\r\n    <mat-tab *ngIf=\"${occpCount}\" label=\"OCCP\" value=\"gateway_devices_16\"></mat-tab>\r\n    <mat-tab *ngIf=\"${customCount}\" label=\"CUSTOM\" value=\"gateway_devices_17\"></mat-tab>\r\n  </mat-tab-group><tb-dashboard-state *ngIf=\"selectedTabIndex == 1\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_1\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 2\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_2\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 3\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_3\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 4\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_4\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 6\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_6\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 7\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_7\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 8\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_8\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 9\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_9\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 10\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_10\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 11\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_11\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 12\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_12\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 13\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_13\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 14\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_14\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 15\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_15\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 16\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_16\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"selectedTabIndex == 17\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_17\"></tb-dashboard-state>\r\n   <tb-dashboard-state *ngIf=\"!selectedTabIndex\" [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_0\"></tb-dashboard-state>\r\n</div>\r\n",
 | 
			
		||||
            "markdownTextPattern": "<div style=\"width: 100%; height: 100%; padding: 0;\" fxFlex fxLayout=\"column\">\n  <mat-tab-group class=devices-tabs>\n    <mat-tab label=\"All\" value=\"gateway_devices_0\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_0\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${mqttCount}\" label=\"MQTT\" value=\"gateway_devices_1\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_1\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${modbusCount}\" label=\"MODBUS\" value=\"gateway_devices_2\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_2\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${grpcCount}\" label=\"GRPC\" value=\"gateway_devices_3\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_3\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${opcuaCount}\" label=\"OPCUA\" value=\"gateway_devices_4\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_4\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${bleCount}\" label=\"BLE\" value=\"gateway_devices_6\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_6\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${requestCount}\" label=\"REQUEST\" value=\"gateway_devices_7\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_7\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${canCount}\" label=\"CAN\" value=\"gateway_devices_8\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_8\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${bacnetCount}\" label=\"BACNET\" value=\"gateway_devices_9\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_9\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${odbcCount}\" label=\"ODBC\" value=\"gateway_devices_10\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_10\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${restCount}\" label=\"REST\" value=\"gateway_devices_11\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_11\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${snmpCount}\" label=\"SNMP\" value=\"gateway_devices_12\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_12\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${ftpCount}\" label=\"FTP\" value=\"gateway_devices_13\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_13\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${socketCount}\" label=\"SOCKET\" value=\"gateway_devices_14\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_14\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${xmppCount}\" label=\"XMPP\" value=\"gateway_devices_15\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_15\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${ocppCount}\" label=\"OCPP\" value=\"gateway_devices_16\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_16\"></tb-dashboard-state>\n    </mat-tab>\n    <mat-tab *ngIf=\"${customCount}\" label=\"CUSTOM\" value=\"gateway_devices_17\">\n      <tb-dashboard-state [ctx]=\"ctx\" fxFlex syncParentStateParams=\"true\" stateId=\"gateway_devices_17\"></tb-dashboard-state>\n    </mat-tab>\n  </mat-tab-group>\n</div>\n",
 | 
			
		||||
            "applyDefaultMarkdownStyle": false,
 | 
			
		||||
            "markdownCss": ".mat-mdc-form-field-subscript-wrapper {\n    display: none !important;\n}"
 | 
			
		||||
            "markdownCss": ".mat-mdc-form-field-subscript-wrapper {\n    display: none !important;\n}\n\n.devices-tabs {\n    height: 100%;\n}\n\n::ng-deep .mat-mdc-tab-body-wrapper {\n  height: 100%;\n}"
 | 
			
		||||
          },
 | 
			
		||||
          "title": "Gateway devices",
 | 
			
		||||
          "showTitleIcon": false,
 | 
			
		||||
@ -6208,7 +6208,7 @@
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      "gateway_devices_16": {
 | 
			
		||||
        "name": "gateway_devices_occp",
 | 
			
		||||
        "name": "gateway_devices_ocpp",
 | 
			
		||||
        "root": false,
 | 
			
		||||
        "layouts": {
 | 
			
		||||
          "main": {
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@
 | 
			
		||||
<div [formGroup]="gatewayConfigGroup" class="gateway-config-container">
 | 
			
		||||
  <div class="content-wrapper">
 | 
			
		||||
    <mat-toolbar color="primary" [class.page-header]="!dialogRef">
 | 
			
		||||
      <div class="tb-flex space-between">
 | 
			
		||||
      <div class="tb-flex space-between align-center">
 | 
			
		||||
        <h2 translate>gateway.gateway-configuration</h2>
 | 
			
		||||
        <div class="toolbar-actions">
 | 
			
		||||
          <tb-toggle-select [class.dialog-toggle]="!!dialogRef" formControlName="mode" appearance="{{dialogRef ? 'stroked' : 'fill'}}">
 | 
			
		||||
 | 
			
		||||
@ -223,6 +223,7 @@
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <tb-report-strategy
 | 
			
		||||
                    *ngIf="withReportStrategy"
 | 
			
		||||
                    [defaultValue]="ReportStrategyDefaultValue.Key"
 | 
			
		||||
                    formControlName="reportStrategy"
 | 
			
		||||
                    [isExpansionMode]="true"
 | 
			
		||||
                  />
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,8 @@ import {
 | 
			
		||||
import { TbPopoverComponent } from '@shared/components/popover.component';
 | 
			
		||||
import {
 | 
			
		||||
  ModbusDataType,
 | 
			
		||||
  ModbusEditableDataTypes, ModbusFormValue,
 | 
			
		||||
  ModbusEditableDataTypes,
 | 
			
		||||
  ModbusFormValue,
 | 
			
		||||
  ModbusFunctionCodeTranslationsMap,
 | 
			
		||||
  ModbusObjectCountByDataType,
 | 
			
		||||
  ModbusValue,
 | 
			
		||||
@ -37,6 +38,7 @@ import {
 | 
			
		||||
  ModifierTypesMap,
 | 
			
		||||
  noLeadTrailSpacesRegex,
 | 
			
		||||
  nonZeroFloat,
 | 
			
		||||
  ReportStrategyDefaultValue,
 | 
			
		||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
 | 
			
		||||
import { CommonModule } from '@angular/common';
 | 
			
		||||
import { SharedModule } from '@shared/shared.module';
 | 
			
		||||
@ -91,6 +93,7 @@ export class ModbusDataKeysPanelComponent implements OnInit, OnDestroy {
 | 
			
		||||
  readonly ModbusEditableDataTypes = ModbusEditableDataTypes;
 | 
			
		||||
  readonly ModbusFunctionCodeTranslationsMap = ModbusFunctionCodeTranslationsMap;
 | 
			
		||||
  readonly ModifierTypesMap = ModifierTypesMap;
 | 
			
		||||
  readonly ReportStrategyDefaultValue = ReportStrategyDefaultValue;
 | 
			
		||||
 | 
			
		||||
  private destroy$ = new Subject<void>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -62,6 +62,14 @@
 | 
			
		||||
    </mat-toolbar>
 | 
			
		||||
    <div class="table-container">
 | 
			
		||||
      <table mat-table [dataSource]="dataSource">
 | 
			
		||||
        <ng-container [matColumnDef]="'deviceName'">
 | 
			
		||||
          <mat-header-cell *matHeaderCellDef class="table-value-column">
 | 
			
		||||
            <div tbTruncateWithTooltip>{{ 'gateway.device-name' | translate }}</div>
 | 
			
		||||
          </mat-header-cell>
 | 
			
		||||
          <mat-cell *matCellDef="let slave" class="table-value-column">
 | 
			
		||||
            <div tbTruncateWithTooltip>{{ slave['deviceName'] }}</div>
 | 
			
		||||
          </mat-cell>
 | 
			
		||||
        </ng-container>
 | 
			
		||||
        <ng-container [matColumnDef]="'info'">
 | 
			
		||||
          <mat-header-cell *matHeaderCellDef class="table-value-column">
 | 
			
		||||
            {{ 'gateway.info' | translate }}
 | 
			
		||||
@ -80,7 +88,7 @@
 | 
			
		||||
        </ng-container>
 | 
			
		||||
        <ng-container [matColumnDef]="'type'">
 | 
			
		||||
          <mat-header-cell *matHeaderCellDef class="table-value-column">
 | 
			
		||||
            <div tbTruncateWithTooltip>{{ 'gateway.client-communication-type' | translate }}</div>
 | 
			
		||||
            <div>{{ 'gateway.type' | translate }}</div>
 | 
			
		||||
          </mat-header-cell>
 | 
			
		||||
          <mat-cell *matCellDef="let slave" class="table-value-column">
 | 
			
		||||
            {{ ModbusProtocolLabelsMap.get(slave['type']) }}
 | 
			
		||||
@ -121,8 +129,8 @@
 | 
			
		||||
            </div>
 | 
			
		||||
          </mat-cell>
 | 
			
		||||
        </ng-container>
 | 
			
		||||
        <mat-header-row [ngClass]="{'mat-row-select': true}" *matHeaderRowDef="['info', 'unitId', 'type', 'actions']; sticky: true"></mat-header-row>
 | 
			
		||||
        <mat-row *matRowDef="let slave; columns: ['info', 'unitId', 'type', 'actions']"></mat-row>
 | 
			
		||||
        <mat-header-row [ngClass]="{'mat-row-select': true}" *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">
 | 
			
		||||
 | 
			
		||||
@ -35,6 +35,7 @@ import {
 | 
			
		||||
  ModbusSlaveInfo,
 | 
			
		||||
  noLeadTrailSpacesRegex,
 | 
			
		||||
  PortLimits,
 | 
			
		||||
  ReportStrategyDefaultValue,
 | 
			
		||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
 | 
			
		||||
import { Subject } from 'rxjs';
 | 
			
		||||
import { DialogComponent } from '@shared/components/dialog.component';
 | 
			
		||||
@ -64,6 +65,7 @@ export abstract class ModbusSlaveDialogAbstract<Component, Config> extends Dialo
 | 
			
		||||
  readonly ModbusParityLabelsMap = ModbusParityLabelsMap;
 | 
			
		||||
  readonly ModbusProtocolLabelsMap = ModbusProtocolLabelsMap;
 | 
			
		||||
  readonly ModbusMethodLabelsMap = ModbusMethodLabelsMap;
 | 
			
		||||
  readonly ReportStrategyDefaultValue = ReportStrategyDefaultValue;
 | 
			
		||||
  readonly modbusHelpLink =
 | 
			
		||||
    helpBaseUrl + '/docs/iot-gateway/config/modbus/#section-master-description-and-configuration-parameters';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -218,7 +218,7 @@
 | 
			
		||||
          </mat-slide-toggle>
 | 
			
		||||
        </div>
 | 
			
		||||
        <ng-template #reportStrategy>
 | 
			
		||||
          <tb-report-strategy formControlName="reportStrategy" [isExpansionMode]="true"/>
 | 
			
		||||
          <tb-report-strategy [defaultValue]="ReportStrategyDefaultValue.Device" formControlName="reportStrategy" [isExpansionMode]="true"/>
 | 
			
		||||
        </ng-template>
 | 
			
		||||
        <div class="tb-form-panel stroked">
 | 
			
		||||
          <mat-expansion-panel class="tb-settings">
 | 
			
		||||
 | 
			
		||||
@ -34,6 +34,7 @@ import {
 | 
			
		||||
} from '@angular/forms';
 | 
			
		||||
import {
 | 
			
		||||
  ReportStrategyConfig,
 | 
			
		||||
  ReportStrategyDefaultValue,
 | 
			
		||||
  ReportStrategyType,
 | 
			
		||||
  ReportStrategyTypeTranslationsMap
 | 
			
		||||
} from '@home/components/widget/lib/gateway/gateway-widget.models';
 | 
			
		||||
@ -43,7 +44,7 @@ import { CommonModule } from '@angular/common';
 | 
			
		||||
import {
 | 
			
		||||
  ModbusSecurityConfigComponent
 | 
			
		||||
} from '@home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component';
 | 
			
		||||
import { coerceBoolean } from '@shared/decorators/coercion';
 | 
			
		||||
import { coerceBoolean, coerceNumber } from '@shared/decorators/coercion';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
  selector: 'tb-report-strategy',
 | 
			
		||||
@ -73,6 +74,9 @@ export class ReportStrategyComponent implements ControlValueAccessor, OnDestroy
 | 
			
		||||
  @coerceBoolean()
 | 
			
		||||
  @Input() isExpansionMode = false;
 | 
			
		||||
 | 
			
		||||
  @coerceNumber()
 | 
			
		||||
  @Input() defaultValue = ReportStrategyDefaultValue.Key;
 | 
			
		||||
 | 
			
		||||
  reportStrategyFormGroup: UntypedFormGroup;
 | 
			
		||||
  showStrategyControl: FormControl<boolean>;
 | 
			
		||||
 | 
			
		||||
@ -90,7 +94,7 @@ export class ReportStrategyComponent implements ControlValueAccessor, OnDestroy
 | 
			
		||||
 | 
			
		||||
    this.reportStrategyFormGroup = this.fb.group({
 | 
			
		||||
      type: [{ value: ReportStrategyType.OnReportPeriod, disabled: true }, []],
 | 
			
		||||
      reportPeriod: [{ value: 5000, disabled: true }, [Validators.required]],
 | 
			
		||||
      reportPeriod: [{ value: this.defaultValue, disabled: true }, [Validators.required]],
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    this.observeStrategyFormChange();
 | 
			
		||||
@ -109,7 +113,7 @@ export class ReportStrategyComponent implements ControlValueAccessor, OnDestroy
 | 
			
		||||
    if (reportStrategyConfig) {
 | 
			
		||||
      this.reportStrategyFormGroup.enable({emitEvent: false});
 | 
			
		||||
    }
 | 
			
		||||
    const { type = ReportStrategyType.OnReportPeriod, reportPeriod = 5000 } = reportStrategyConfig ?? {};
 | 
			
		||||
    const { type = ReportStrategyType.OnReportPeriod, reportPeriod = this.defaultValue } = reportStrategyConfig ?? {};
 | 
			
		||||
    this.reportStrategyFormGroup.setValue({ type, reportPeriod }, {emitEvent: false});
 | 
			
		||||
    this.onTypeChange(type);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -23,7 +23,7 @@
 | 
			
		||||
      <button *ngIf="dataSource?.data?.length"
 | 
			
		||||
              mat-icon-button
 | 
			
		||||
              [disabled]="isLoading$ | async"
 | 
			
		||||
              (click)="addConnector($event)"
 | 
			
		||||
              (click)="onAddConnector($event)"
 | 
			
		||||
              matTooltip="{{ 'action.add' | translate }}"
 | 
			
		||||
              matTooltipPosition="above">
 | 
			
		||||
        <mat-icon>add</mat-icon>
 | 
			
		||||
@ -33,7 +33,7 @@
 | 
			
		||||
      <section *ngIf="!dataSource?.data?.length" fxLayoutAlign="center center"
 | 
			
		||||
               class="mat-headline-5 tb-absolute-fill tb-add-new">
 | 
			
		||||
        <button mat-button class="connector"
 | 
			
		||||
        (click)="addConnector($event)">
 | 
			
		||||
        (click)="onAddConnector($event)">
 | 
			
		||||
          <mat-icon class="tb-mat-96">add</mat-icon>
 | 
			
		||||
          <span>{{ 'gateway.add-connector' | translate }}</span>
 | 
			
		||||
        </button>
 | 
			
		||||
@ -244,7 +244,7 @@
 | 
			
		||||
        <button mat-raised-button color="primary"
 | 
			
		||||
                type="button"
 | 
			
		||||
                [disabled]="!connectorForm.dirty || connectorForm.invalid"
 | 
			
		||||
                (click)="saveConnector(false)">
 | 
			
		||||
                (click)="onSaveConnector()">
 | 
			
		||||
          {{ 'action.save' | translate }}
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
@ -315,6 +315,7 @@
 | 
			
		||||
      </mat-slide-toggle>
 | 
			
		||||
    </div>
 | 
			
		||||
    <tb-report-strategy
 | 
			
		||||
      [defaultValue]="ReportStrategyDefaultValue.Connector"
 | 
			
		||||
      *ngIf="connectorForm.get('type').value === ConnectorType.MODBUS && connectorForm.get('configVersion').value === GatewayVersion.Current"
 | 
			
		||||
      formControlName="reportStrategy"
 | 
			
		||||
    />
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,7 @@ import { MatTableDataSource } from '@angular/material/table';
 | 
			
		||||
import { ActionNotificationShow } from '@core/notification/notification.actions';
 | 
			
		||||
import { DialogService } from '@core/services/dialog.service';
 | 
			
		||||
import { WidgetContext } from '@home/models/widget-component.models';
 | 
			
		||||
import { camelCase, deepClone, generateSecret, isEqual, isString } from '@core/utils';
 | 
			
		||||
import { camelCase, deepClone, isEqual, isString } from '@core/utils';
 | 
			
		||||
import { NULL_UUID } from '@shared/models/id/has-uuid';
 | 
			
		||||
import { IWidgetSubscription, WidgetSubscriptionOptions } from '@core/api/widget-api.models';
 | 
			
		||||
import { DatasourceType, widgetType } from '@shared/models/widget.models';
 | 
			
		||||
@ -60,6 +60,8 @@ import {
 | 
			
		||||
  GatewayLogLevel,
 | 
			
		||||
  noLeadTrailSpacesRegex,
 | 
			
		||||
  GatewayVersion,
 | 
			
		||||
  ReportStrategyDefaultValue,
 | 
			
		||||
  ReportStrategyType,
 | 
			
		||||
} from './gateway-widget.models';
 | 
			
		||||
import { MatDialog } from '@angular/material/dialog';
 | 
			
		||||
import { AddConnectorDialogComponent } from '@home/components/widget/lib/gateway/dialog/add-connector-dialog.component';
 | 
			
		||||
@ -103,6 +105,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
  readonly GatewayConnectorTypesTranslatesMap = GatewayConnectorDefaultTypesTranslatesMap;
 | 
			
		||||
  readonly ConnectorConfigurationModes = ConfigurationModes;
 | 
			
		||||
  readonly GatewayVersion = GatewayVersion;
 | 
			
		||||
  readonly ReportStrategyDefaultValue = ReportStrategyDefaultValue;
 | 
			
		||||
 | 
			
		||||
  pageLink: PageLink;
 | 
			
		||||
  dataSource: MatTableDataSource<GatewayAttributeData>;
 | 
			
		||||
@ -170,18 +173,21 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
    super.ngOnDestroy();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  saveConnector(isNew = true): void {
 | 
			
		||||
    const value = this.getConnectorData();
 | 
			
		||||
  onSaveConnector(): void {
 | 
			
		||||
    this.saveConnector(this.getUpdatedConnectorData(this.connectorForm.value), false);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private saveConnector(connector: GatewayConnector, isNew = true): void {
 | 
			
		||||
    const scope = (isNew || this.activeConnectors.includes(this.initialConnector.name))
 | 
			
		||||
      ? AttributeScope.SHARED_SCOPE
 | 
			
		||||
      : AttributeScope.SERVER_SCOPE;
 | 
			
		||||
 | 
			
		||||
    forkJoin(this.getEntityAttributeTasks(value, scope)).pipe(take(1)).subscribe(_ => {
 | 
			
		||||
      this.showToast(!this.initialConnector
 | 
			
		||||
    forkJoin(this.getEntityAttributeTasks(connector, scope)).pipe(take(1)).subscribe(_ => {
 | 
			
		||||
      this.showToast(isNew
 | 
			
		||||
        ? this.translate.instant('gateway.connector-created')
 | 
			
		||||
        : this.translate.instant('gateway.connector-updated')
 | 
			
		||||
      );
 | 
			
		||||
      this.initialConnector = value;
 | 
			
		||||
      this.initialConnector = connector;
 | 
			
		||||
      this.updateData(true);
 | 
			
		||||
      this.connectorForm.markAsPristine();
 | 
			
		||||
    });
 | 
			
		||||
@ -237,8 +243,8 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private getConnectorData(): GatewayConnector {
 | 
			
		||||
    const value = { ...this.connectorForm.value };
 | 
			
		||||
  private getUpdatedConnectorData(connector: GatewayConnector): GatewayConnector {
 | 
			
		||||
    const value = {...connector };
 | 
			
		||||
    value.configuration = `${camelCase(value.name)}.json`;
 | 
			
		||||
    delete value.basicConfig;
 | 
			
		||||
 | 
			
		||||
@ -249,6 +255,16 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
      delete value.class;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (value.type === ConnectorType.MODBUS && value.configVersion === GatewayVersion.Current) {
 | 
			
		||||
      if (!value.reportStrategy) {
 | 
			
		||||
        value.reportStrategy = {
 | 
			
		||||
          type: ReportStrategyType.OnReportPeriod,
 | 
			
		||||
          reportPeriod: ReportStrategyDefaultValue.Connector
 | 
			
		||||
        };
 | 
			
		||||
        delete value.sendDataOnlyOnChange;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.gatewayVersion && !value.configVersion) {
 | 
			
		||||
      value.configVersion = this.gatewayVersion;
 | 
			
		||||
    }
 | 
			
		||||
@ -472,7 +488,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
    return (connector && this.activeConnectors.includes(connectorName)) ? (connector.data[0][1] || 0) : 'Inactive';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  addConnector(event?: Event): void {
 | 
			
		||||
  onAddConnector(event?: Event): void {
 | 
			
		||||
    event?.stopPropagation();
 | 
			
		||||
 | 
			
		||||
    this.confirmConnectorChange()
 | 
			
		||||
@ -482,25 +498,42 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
        switchMap(() => this.openAddConnectorDialog()),
 | 
			
		||||
        filter(Boolean),
 | 
			
		||||
      )
 | 
			
		||||
      .subscribe(value => {
 | 
			
		||||
      .subscribe(connector => this.addConnector(connector));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private addConnector(connector: GatewayConnector): void {
 | 
			
		||||
    if (this.connectorForm.disabled) {
 | 
			
		||||
      this.connectorForm.enable();
 | 
			
		||||
    }
 | 
			
		||||
        if (!value.configurationJson) {
 | 
			
		||||
          value.configurationJson = {} as ConnectorBaseConfig;
 | 
			
		||||
    if (!connector.configurationJson) {
 | 
			
		||||
      connector.configurationJson = {} as ConnectorBaseConfig;
 | 
			
		||||
    }
 | 
			
		||||
        value.basicConfig = value.configurationJson;
 | 
			
		||||
        this.initialConnector = value;
 | 
			
		||||
        this.connectorForm.patchValue(value, {emitEvent: false});
 | 
			
		||||
        this.generate('basicConfig.broker.clientId');
 | 
			
		||||
        if (this.connectorForm.get('type').value === value.type || !this.allowBasicConfig.has(value.type)) {
 | 
			
		||||
          this.saveConnector();
 | 
			
		||||
    connector.basicConfig = connector.configurationJson;
 | 
			
		||||
    this.initialConnector = connector;
 | 
			
		||||
 | 
			
		||||
    const previousType = this.connectorForm.get('type').value;
 | 
			
		||||
 | 
			
		||||
    this.setInitialConnectorValues(connector);
 | 
			
		||||
 | 
			
		||||
    this.saveConnector(this.getUpdatedConnectorData(connector));
 | 
			
		||||
 | 
			
		||||
    if (!previousType || previousType === connector.type || !this.allowBasicConfig.has(connector.type)) {
 | 
			
		||||
      this.patchBasicConfigConnector(connector);
 | 
			
		||||
    } else {
 | 
			
		||||
      this.basicConfigInitSubject.pipe(take(1)).subscribe(() => {
 | 
			
		||||
            this.saveConnector();
 | 
			
		||||
        this.patchBasicConfigConnector(connector);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private setInitialConnectorValues(connector: GatewayConnector): void {
 | 
			
		||||
    this.toggleReportStrategy(connector.type);
 | 
			
		||||
    this.connectorForm.get('mode').setValue(this.allowBasicConfig.has(connector.type)
 | 
			
		||||
      ? connector.mode ?? ConfigurationModes.BASIC
 | 
			
		||||
      : null, {emitEvent: false}
 | 
			
		||||
    );
 | 
			
		||||
    this.connectorForm.get('configVersion').setValue(connector.configVersion, {emitEvent: false});
 | 
			
		||||
    this.connectorForm.get('type').setValue(connector.type, {emitEvent: false});
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private openAddConnectorDialog(): Observable<GatewayConnector> {
 | 
			
		||||
@ -514,10 +547,6 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
    }).afterClosed();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  generate(formControlName: string): void {
 | 
			
		||||
    this.connectorForm.get(formControlName)?.patchValue('tb_gw_' + generateSecret(5));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uniqNameRequired(): ValidatorFn {
 | 
			
		||||
    return (control: UntypedFormControl) => {
 | 
			
		||||
      const newName = control.value?.trim().toLowerCase();
 | 
			
		||||
@ -607,7 +636,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
 | 
			
		||||
        const active = attributes.find(data => data.key === 'active').value;
 | 
			
		||||
        const lastDisconnectedTime = attributes.find(data => data.key === 'lastDisconnectTime')?.value;
 | 
			
		||||
        const lastConnectedTime = attributes.find(data => data.key === 'lastConnectTime').value;
 | 
			
		||||
        const lastConnectedTime = attributes.find(data => data.key === 'lastConnectTime')?.value;
 | 
			
		||||
 | 
			
		||||
        this.isGatewayActive = this.getGatewayStatus(active, lastConnectedTime, lastDisconnectedTime);
 | 
			
		||||
      });
 | 
			
		||||
@ -804,7 +833,6 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateConnector(connector: GatewayConnector): void {
 | 
			
		||||
    this.toggleReportStrategy(connector.type);
 | 
			
		||||
    switch (connector.type) {
 | 
			
		||||
      case ConnectorType.MQTT:
 | 
			
		||||
      case ConnectorType.OPCUA:
 | 
			
		||||
@ -819,8 +847,7 @@ export class GatewayConnectorComponent extends PageComponent implements AfterVie
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private updateBasicConfigConnector(connector: GatewayConnector): void {
 | 
			
		||||
    this.connectorForm.get('mode').setValue(connector.mode || ConfigurationModes.BASIC, {emitEvent: false});
 | 
			
		||||
    this.connectorForm.get('configVersion').setValue(connector.configVersion, {emitEvent: false});
 | 
			
		||||
    this.setInitialConnectorValues(connector);
 | 
			
		||||
    if ((!connector.mode || connector.mode === ConfigurationModes.BASIC) && this.connectorForm.get('type').value !== connector.type) {
 | 
			
		||||
      this.basicConfigInitSubject.asObservable().pipe(take(1)).subscribe(() => {
 | 
			
		||||
        this.patchBasicConfigConnector(connector);
 | 
			
		||||
 | 
			
		||||
@ -123,6 +123,9 @@ export interface GatewayConnectorBase {
 | 
			
		||||
  class?: string;
 | 
			
		||||
  mode?: ConfigurationModes;
 | 
			
		||||
  configVersion?: string;
 | 
			
		||||
  reportStrategy?: ReportStrategyConfig;
 | 
			
		||||
  sendDataOnlyOnChange?: boolean;
 | 
			
		||||
  ts?: number;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface GatewayConnector<BaseConfig = ConnectorBaseConfig> extends GatewayConnectorBase {
 | 
			
		||||
@ -645,6 +648,12 @@ export enum ReportStrategyType {
 | 
			
		||||
  OnChangeOrReportPeriod = 'ON_CHANGE_OR_REPORT_PERIOD'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export enum ReportStrategyDefaultValue {
 | 
			
		||||
  Connector = 60000,
 | 
			
		||||
  Device = 30000,
 | 
			
		||||
  Key = 15000
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ReportStrategyTypeTranslationsMap = new Map<ReportStrategyType, string>(
 | 
			
		||||
  [
 | 
			
		||||
    [ReportStrategyType.OnChange, 'gateway.report-strategy.on-change'],
 | 
			
		||||
 | 
			
		||||
@ -2955,7 +2955,6 @@
 | 
			
		||||
        "configuration-delete-dialog-confirm": "Turn Off",
 | 
			
		||||
        "connector-duplicate-name": "Connector with such name already exists.",
 | 
			
		||||
        "connector-side": "Connector side",
 | 
			
		||||
        "client-communication-type": "Client communication type",
 | 
			
		||||
        "payload-type": "Payload type",
 | 
			
		||||
        "platform-side": "Platform side",
 | 
			
		||||
        "JSON": "JSON",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user