From 7b9d8e0a5528e07344cd829267e55c3821b144a7 Mon Sep 17 00:00:00 2001 From: mpetrov Date: Thu, 25 Jul 2024 12:09:26 +0300 Subject: [PATCH] major refactoring --- .../modbus-basic-config.component.ts | 15 +- .../modbus-data-keys-panel.component.html | 13 +- .../modbus-data-keys-panel.component.ts | 92 +++++++---- .../modbus-master-table.component.html | 10 +- .../modbus-master-table.component.scss | 21 +-- .../modbus-master-table.component.ts | 45 +++--- .../modbus-security-config.component.ts | 2 +- .../modbus-slave-config.component.html | 9 +- .../modbus-slave-config.component.scss | 5 - .../modbus-slave-config.component.ts | 151 +++++++++--------- .../modbus-slave-dialog.component.html | 6 +- .../modbus-slave-dialog.component.ts | 122 +++++++------- .../modbus-values/modbus-values.component.ts | 109 ++++++------- .../lib/gateway/gateway-widget.models.ts | 27 +--- .../widget/widget-components.module.ts | 39 ++--- .../home/pipes/gateway-port-tooltip.pipe.ts | 12 +- .../ellipsis-chip-list.directive.ts | 5 +- .../assets/locale/locale.constant-en_US.json | 1 + .../connector-default-configs/modbus.json | 1 + 19 files changed, 340 insertions(+), 345 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.ts index 35e0ee6e61..12143fb6db 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-basic-config/modbus-basic-config.component.ts @@ -68,12 +68,6 @@ import { ModbusMasterTableComponent } from '../modbus-master-table/modbus-master overflow: hidden !important; } } - - :host ::ng-deep { - .mat-mdc-tab-group, .mat-mdc-tab-body-wrapper { - height: 100%; - } - } `] }) @@ -83,10 +77,9 @@ export class ModbusBasicConfigComponent implements ControlValueAccessor, Validat basicFormGroup: FormGroup; - onChange: (value: string) => void; + onChange: (value: ModbusBasicConfig) => void; onTouched: () => void; - protected readonly connectorType = ConnectorType; private destroy$ = new Subject(); constructor(private fb: FormBuilder) { @@ -108,7 +101,7 @@ export class ModbusBasicConfigComponent implements ControlValueAccessor, Validat this.destroy$.complete(); } - registerOnChange(fn: (value: string) => void): void { + registerOnChange(fn: (value: ModbusBasicConfig) => void): void { this.onChange = fn; } @@ -118,8 +111,8 @@ export class ModbusBasicConfigComponent implements ControlValueAccessor, Validat writeValue(basicConfig: ModbusBasicConfig): void { const editedBase = { - slave: basicConfig.slave || {}, - master: basicConfig.master || {}, + slave: basicConfig.slave ?? {}, + master: basicConfig.master ?? {}, }; this.basicFormGroup.setValue(editedBase, {emitEvent: false}); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.html index 048ee94553..5285422bd6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.html @@ -20,7 +20,7 @@
{{ panelTitle | translate }}{{' (' + keysListFormArray.controls.length + ')'}}
+ *ngFor="let keyControl of keysListFormArray.controls; trackBy: trackByControlId; let $index = index; let last = last;">
@@ -99,10 +99,19 @@
-
gateway.address
+
gateway.address
+ + warning +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts index d128e3c246..d0bfcf1e76 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-data-keys-panel/modbus-data-keys-panel.component.ts @@ -14,14 +14,21 @@ /// limitations under the License. /// -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { AbstractControl, FormGroup, UntypedFormArray, UntypedFormBuilder, Validators } from '@angular/forms'; +import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core'; +import { + AbstractControl, + FormArray, + FormGroup, + UntypedFormArray, + UntypedFormBuilder, + UntypedFormGroup, + Validators +} from '@angular/forms'; import { TbPopoverComponent } from '@shared/components/popover.component'; import { ModbusDataType, ModbusFunctionCodeTranslationsMap, ModbusObjectCountByDataType, - ModbusRegisterType, ModbusValue, ModbusValueKey, noLeadTrailSpacesRegex, @@ -31,6 +38,8 @@ import { SharedModule } from '@shared/shared.module'; import { GatewayHelpLinkPipe } from '@home/pipes/gateway-help-link.pipe'; import { generateSecret } from '@core/utils'; import { coerceBoolean } from '@shared/decorators/coercion'; +import { takeUntil } from 'rxjs/operators'; +import { Subject } from 'rxjs'; @Component({ selector: 'tb-modbus-data-keys-panel', @@ -43,7 +52,7 @@ import { coerceBoolean } from '@shared/decorators/coercion'; GatewayHelpLinkPipe, ] }) -export class ModbusDataKeysPanelComponent implements OnInit { +export class ModbusDataKeysPanelComponent implements OnInit, OnDestroy { @coerceBoolean() @Input() isMaster = false; @@ -51,15 +60,13 @@ export class ModbusDataKeysPanelComponent implements OnInit { @Input() addKeyTitle: string; @Input() deleteKeyTitle: string; @Input() noKeysText: string; - @Input() register: ModbusRegisterType; @Input() keysType: ModbusValueKey; @Input() values: ModbusValue[]; @Input() popover: TbPopoverComponent; @Output() keysDataApplied = new EventEmitter>(); - keysListFormArray: UntypedFormArray; - errorText = ''; + keysListFormArray: FormArray; modbusDataTypes = Object.values(ModbusDataType); withFunctionCode = true; functionCodesMap = new Map(); @@ -67,9 +74,12 @@ export class ModbusDataKeysPanelComponent implements OnInit { readonly editableDataTypes = [ModbusDataType.BYTES, ModbusDataType.BITS, ModbusDataType.STRING]; readonly ModbusFunctionCodeTranslationsMap = ModbusFunctionCodeTranslationsMap; - readonly defaultReadFunctionCodes = [3, 4]; - readonly defaultWriteFunctionCodes = [5, 6, 15, 16]; - readonly stringAttrUpdatesWriteFunctionCodes = [6, 16]; + + private destroy$ = new Subject(); + + private readonly defaultReadFunctionCodes = [3, 4]; + private readonly defaultWriteFunctionCodes = [5, 6, 15, 16]; + private readonly stringAttrUpdatesWriteFunctionCodes = [6, 16]; constructor(private fb: UntypedFormBuilder) {} @@ -79,8 +89,13 @@ export class ModbusDataKeysPanelComponent implements OnInit { this.defaultFunctionCodes = this.getDefaultFunctionCodes(); } - trackByKey(_: number, keyControl: AbstractControl): AbstractControl { - return keyControl; + ngOnDestroy(): void { + this.destroy$.next(); + this.destroy$.complete(); + } + + trackByControlId(_: number, keyControl: AbstractControl): string { + return keyControl.value.id; } addKey(): void { @@ -88,7 +103,7 @@ export class ModbusDataKeysPanelComponent implements OnInit { tag: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], value: [{value: '', disabled: !this.isMaster}, [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], type: [ModbusDataType.BYTES, [Validators.required]], - address: [0, [Validators.required]], + address: [null, [Validators.required]], objectsCount: [1, [Validators.required]], functionCode: [this.getDefaultFunctionCodes()[0]], id: [{value: generateSecret(5), disabled: true}], @@ -107,7 +122,7 @@ export class ModbusDataKeysPanelComponent implements OnInit { } cancel(): void { - this.popover?.hide(); + this.popover.hide(); } applyKeysData(): void { @@ -116,32 +131,38 @@ export class ModbusDataKeysPanelComponent implements OnInit { private prepareKeysFormArray(values: ModbusValue[]): UntypedFormArray { const keysControlGroups: Array = []; + if (values) { - values.forEach(keyData => { - const { tag, value, type, address, objectsCount, functionCode } = keyData; - const dataKeyFormGroup = this.fb.group({ - tag: [tag, [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], - value: [{value, disabled: !this.isMaster}, [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], - type: [type, [Validators.required]], - address: [address, [Validators.required]], - objectsCount: [objectsCount, [Validators.required]], - functionCode: [functionCode, []], - id: [{value: generateSecret(5), disabled: true}], - }); + values.forEach(value => { + const dataKeyFormGroup = this.createDataKeyFormGroup(value); this.observeKeyDataType(dataKeyFormGroup); - this.functionCodesMap.set(dataKeyFormGroup.get('id').value, this.getFunctionCodes(type)); + this.functionCodesMap.set(dataKeyFormGroup.get('id').value, this.getFunctionCodes(value.type)); keysControlGroups.push(dataKeyFormGroup); }); } + return this.fb.array(keysControlGroups); } + private createDataKeyFormGroup(modbusValue: ModbusValue): FormGroup { + const { tag, value, type, address, objectsCount, functionCode } = modbusValue; + + return this.fb.group({ + tag: [tag, [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], + value: [{ value, disabled: !this.isMaster }, [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], + type: [type, [Validators.required]], + address: [address, [Validators.required]], + objectsCount: [objectsCount, [Validators.required]], + functionCode: [functionCode, [Validators.required]], + id: [{ value: generateSecret(5), disabled: true }], + }); + } + private observeKeyDataType(keyFormGroup: FormGroup): void { - keyFormGroup.get('type').valueChanges.subscribe(dataType => { - const objectsCountControl = keyFormGroup.get('objectsCount'); + keyFormGroup.get('type').valueChanges.pipe(takeUntil(this.destroy$)).subscribe(dataType => { if (!this.editableDataTypes.includes(dataType)) { - objectsCountControl.patchValue(ModbusObjectCountByDataType[dataType]); + keyFormGroup.get('objectsCount').patchValue(ModbusObjectCountByDataType[dataType], {emitEvent: false}); } this.functionCodesMap.set(keyFormGroup.get('id').value, this.getFunctionCodes(dataType)); }); @@ -149,20 +170,21 @@ export class ModbusDataKeysPanelComponent implements OnInit { private getFunctionCodes(dataType: ModbusDataType): number[] { if (this.keysType === ModbusValueKey.ATTRIBUTES_UPDATES) { - if (dataType === ModbusDataType.STRING) { - return this.stringAttrUpdatesWriteFunctionCodes; - } - return this.defaultWriteFunctionCodes; + return dataType === ModbusDataType.STRING + ? this.stringAttrUpdatesWriteFunctionCodes + : this.defaultWriteFunctionCodes; } + const functionCodes = [...this.defaultReadFunctionCodes]; if (dataType === ModbusDataType.BITS) { const bitsFunctionCodes = [1, 2]; - bitsFunctionCodes.forEach(code => functionCodes.push(code)); + functionCodes.push(...bitsFunctionCodes); functionCodes.sort(); } if (this.keysType === ModbusValueKey.RPC_REQUESTS) { - this.defaultWriteFunctionCodes.forEach(code => functionCodes.push(code)); + functionCodes.push(...this.defaultWriteFunctionCodes); } + return functionCodes; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html index 2e92d80c9f..e16aa0c51f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.html @@ -60,18 +60,18 @@
- + {{ 'gateway.name' | translate }} - + {{ mapping['name'] }} - + {{ 'gateway.client-communication-type' | translate }} - + {{ ModbusProtocolLabelsMap.get(mapping['type']) }} @@ -111,7 +111,7 @@ - +
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.scss index 82cead07a4..e9a5d3ebcd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.scss @@ -19,19 +19,15 @@ width: 100%; height: 100%; display: block; + .tb-master-table { + .tb-master-table-content { width: 100%; height: 100%; background: #fff; overflow: hidden; - &.tb-outlined-border { - 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; - } - .mat-toolbar-tools{ min-height: auto; } @@ -49,25 +45,17 @@ .table-container { overflow: auto; + .mat-mdc-table { table-layout: fixed; min-width: 450px; .table-value-column { padding: 0 12px; - width: 23%; - - &.request-column { - width: 38%; - } + width: 38%; } } } - - .ellipsis { - overflow: hidden; - text-overflow: ellipsis; - } } } @@ -91,6 +79,7 @@ :host ::ng-deep { mat-cell.tb-value-cell { cursor: pointer; + .mat-icon { height: 24px; width: 24px; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.ts index 10b1e5bbbe..7ca5c8a7fa 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-master-table/modbus-master-table.component.ts @@ -17,6 +17,7 @@ import { AfterViewInit, ChangeDetectionStrategy, + ChangeDetectorRef, Component, ElementRef, forwardRef, @@ -76,15 +77,12 @@ export class ModbusMasterTableComponent implements ControlValueAccessor, Validat textSearchMode = false; dataSource: SlavesDatasource; - hidePageSize = false; - activeValue = false; - dirtyValue = false; masterFormGroup: UntypedFormGroup; textSearch = this.fb.control('', {nonNullable: true}); readonly ModbusProtocolLabelsMap = ModbusProtocolLabelsMap; - private onChange: (value: string) => void = () => {}; + private onChange: (value: ModbusMasterConfig) => void = () => {}; private onTouched: () => void = () => {}; private destroy$ = new Subject(); @@ -93,10 +91,10 @@ export class ModbusMasterTableComponent implements ControlValueAccessor, Validat public translate: TranslateService, public dialog: MatDialog, private dialogService: DialogService, - private fb: FormBuilder + private fb: FormBuilder, + private cdr: ChangeDetectorRef, ) { - this.masterFormGroup = this.fb.group({ slaves: this.fb.array([])}); - this.dirtyValue = !this.activeValue; + this.masterFormGroup = this.fb.group({ slaves: this.fb.array([]) }); this.dataSource = new SlavesDatasource(); } @@ -124,13 +122,10 @@ export class ModbusMasterTableComponent implements ControlValueAccessor, Validat debounceTime(150), distinctUntilChanged((prev, current) => (prev ?? '') === current.trim()), takeUntil(this.destroy$) - ).subscribe((text) => { - const searchText = text.trim(); - this.updateTableData(this.slaves.value, searchText.trim()); - }); + ).subscribe(text => this.updateTableData(this.slaves.value, text.trim())); } - registerOnChange(fn: (value: string) => void): void { + registerOnChange(fn: (value: ModbusMasterConfig) => void): void { this.onChange = fn; } @@ -151,10 +146,10 @@ export class ModbusMasterTableComponent implements ControlValueAccessor, Validat enterFilterMode(): void { this.textSearchMode = true; - setTimeout(() => { - this.searchInputField.nativeElement.focus(); - this.searchInputField.nativeElement.setSelectionRange(0, 0); - }, 10); + this.cdr.detectChanges(); + const searchInput = this.searchInputField.nativeElement; + searchInput.focus(); + searchInput.setSelectionRange(0, 0); } exitFilterMode(): void { @@ -167,19 +162,20 @@ export class ModbusMasterTableComponent implements ControlValueAccessor, Validat if ($event) { $event.stopPropagation(); } - const value = isDefinedAndNotNull(index) ? this.slaves.at(index).value : {}; + const withIndex = isDefinedAndNotNull(index); + const value = withIndex ? this.slaves.at(index).value : {}; this.dialog.open(ModbusSlaveDialogComponent, { disableClose: true, panelClass: ['tb-dialog', 'tb-fullscreen-dialog'], data: { value, - buttonTitle: isUndefinedOrNull(index) ? 'action.add' : 'action.apply' + buttonTitle: withIndex ? 'action.add' : 'action.apply' } }).afterClosed() .pipe(take(1), takeUntil(this.destroy$)) .subscribe(res => { if (res) { - if (isDefinedAndNotNull(index)) { + if (withIndex) { this.slaves.at(index).patchValue(res); } else { this.slaves.push(this.fb.control(res)); @@ -199,7 +195,7 @@ export class ModbusMasterTableComponent implements ControlValueAccessor, Validat this.translate.instant('action.no'), this.translate.instant('action.yes'), true - ).subscribe((result) => { + ).pipe(take(1), takeUntil(this.destroy$)).subscribe((result) => { if (result) { this.slaves.removeAt(index); this.masterFormGroup.markAsDirty(); @@ -208,15 +204,14 @@ export class ModbusMasterTableComponent implements ControlValueAccessor, Validat } private updateTableData(data: SlaveConfig[], textSearch?: string): void { - let tableValue = data; if (textSearch) { - tableValue = tableValue.filter(value => - Object.values(value).some(val => - val.toString().toLowerCase().includes(textSearch.toLowerCase()) + data = data.filter(item => + Object.values(item).some(value => + value.toString().toLowerCase().includes(textSearch.toLowerCase()) ) ); } - this.dataSource.loadData(tableValue); + this.dataSource.loadData(data); } private pushDataAsFormArrays(slaves: SlaveConfig[]): void { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts index 75328d1264..bc40727b55 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-security-config/modbus-security-config.component.ts @@ -85,7 +85,7 @@ export class ModbusSecurityConfigComponent implements ControlValueAccessor, Vali keyfile: ['', [Validators.pattern(noLeadTrailSpacesRegex)]], password: ['', [Validators.pattern(noLeadTrailSpacesRegex)]], server_hostname: ['', [Validators.pattern(noLeadTrailSpacesRegex)]], - reqclicert: [{value: false, disabled: true}, []], + reqclicert: [{value: false, disabled: true}], }); this.observeValueChanges(); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html index 25a07ccfa5..56fc579361 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.html @@ -86,11 +86,8 @@ warning @@ -188,7 +185,7 @@
gateway.advanced-connection-settings
-
+
gateway.byte-order
diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.scss index f3b39e3508..0c2f9240be 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.scss @@ -16,11 +16,6 @@ $server-config-header-height: 132px; :host { - .nested-expansion-header { - ::ng-deep .mat-content { - height: 100%; - } - } .slave-content { height: calc(100% - #{$server-config-header-height}); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts index 189ca75762..d44272734d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-config/modbus-slave-config.component.ts @@ -18,9 +18,9 @@ import { ChangeDetectionStrategy, Component, forwardRef, OnDestroy } from '@angu import { ControlValueAccessor, FormBuilder, + FormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormControl, UntypedFormGroup, ValidationErrors, Validator, @@ -78,7 +78,7 @@ import { isEqual } from '@core/utils'; export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validator, OnDestroy { slaveConfigFormGroup: UntypedFormGroup; - showSecurityControl: UntypedFormControl; + showSecurityControl: FormControl; ModbusProtocolLabelsMap = ModbusProtocolLabelsMap; ModbusMethodLabelsMap = ModbusMethodLabelsMap; portLimits = PortLimits; @@ -89,8 +89,9 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat readonly modbusOrderType = Object.values(ModbusOrderType); readonly ModbusProtocolType = ModbusProtocolType; readonly modbusBaudrates = ModbusBaudrates; - readonly serialSpecificControlKeys = ['serialPort', 'baudrate']; - readonly tcpUdpSpecificControlKeys = ['port', 'security', 'host']; + + private readonly serialSpecificControlKeys = ['serialPort', 'baudrate']; + private readonly tcpUdpSpecificControlKeys = ['port', 'security', 'host']; private onChange: (value: SlaveConfig) => void; private onTouched: () => void; @@ -100,18 +101,18 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat constructor(private fb: FormBuilder) { this.showSecurityControl = this.fb.control(false); this.slaveConfigFormGroup = this.fb.group({ - type: [ModbusProtocolType.TCP, []], + type: [ModbusProtocolType.TCP], host: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], port: [null, [Validators.required, Validators.min(PortLimits.MIN), Validators.max(PortLimits.MAX)]], serialPort: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], - method: [ModbusMethodType.RTU, []], + method: [ModbusMethodType.SOCKET], unitId: [0, [Validators.required]], - baudrate: [this.ModbusProtocolType[0], []], + baudrate: [this.modbusBaudrates[0]], deviceName: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], deviceType: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], - pollPeriod: [5000, []], - sendDataToThingsBoard: [false, []], - byteOrder:[ModbusOrderType.BIG, []], + pollPeriod: [5000], + sendDataToThingsBoard: [false], + byteOrder:[ModbusOrderType.BIG], security: [], identity: this.fb.group({ vendorName: ['', [Validators.pattern(noLeadTrailSpacesRegex)]], @@ -123,22 +124,16 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat values: [], }); - this.slaveConfigFormGroup.valueChanges.pipe( - takeUntil(this.destroy$) - ).subscribe((value: SlaveConfig) => { - if (value.type === ModbusProtocolType.Serial) { - value.port = value.serialPort; - delete value.serialPort; - } - this.onChange(value); - this.onTouched(); - }); - + this.observeValueChanges(); this.observeTypeChange(); this.observeFormEnable(); this.observeShowSecurity(); } + get isSlaveEnabled(): boolean { + return this.slaveConfigFormGroup.get('sendDataToThingsBoard').value; + } + ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); @@ -154,7 +149,7 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat validate(): ValidationErrors | null { return this.slaveConfigFormGroup.valid ? null : { - serverConfigFormGroup: { valid: false } + slaveConfigFormGroup: { valid: false } }; } @@ -164,18 +159,29 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat this.updateFormEnableState(slaveConfig.sendDataToThingsBoard); } - private observeTypeChange(): void { - this.slaveConfigFormGroup.get('type').valueChanges.pipe(takeUntil(this.destroy$)).subscribe(type => { - this.updateFormEnableState(this.slaveConfigFormGroup.get('sendDataToThingsBoard').value); + private observeValueChanges(): void { + this.slaveConfigFormGroup.valueChanges.pipe( + takeUntil(this.destroy$) + ).subscribe((value: SlaveConfig) => { + if (value.type === ModbusProtocolType.Serial) { + value.port = value.serialPort; + delete value.serialPort; + } + this.onChange(value); + this.onTouched(); }); } + private observeTypeChange(): void { + this.slaveConfigFormGroup.get('type').valueChanges + .pipe(takeUntil(this.destroy$)) + .subscribe(() => this.updateFormEnableState(this.isSlaveEnabled)); + } + private observeFormEnable(): void { this.slaveConfigFormGroup.get('sendDataToThingsBoard').valueChanges - .pipe(startWith(this.slaveConfigFormGroup.get('sendDataToThingsBoard').value), takeUntil(this.destroy$)) - .subscribe(value => { - this.updateFormEnableState(value); - }); + .pipe(startWith(this.isSlaveEnabled), takeUntil(this.destroy$)) + .subscribe(value => this.updateFormEnableState(value)); } private updateFormEnableState(enabled: boolean): void { @@ -192,11 +198,13 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat } private observeShowSecurity(): void { - this.showSecurityControl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => this.updateSecurityEnable(value)); + this.showSecurityControl.valueChanges + .pipe(takeUntil(this.destroy$)) + .subscribe(value => this.updateSecurityEnable(value)); } - private updateSecurityEnable(isEnabled: boolean): void { - if (isEnabled && this.slaveConfigFormGroup.get('sendDataToThingsBoard').value) { + private updateSecurityEnable(securityEnabled: boolean): void { + if (securityEnabled && this.isSlaveEnabled) { this.slaveConfigFormGroup.get('security').enable({emitEvent: false}); } else { this.slaveConfigFormGroup.get('security').disable({emitEvent: false}); @@ -204,63 +212,58 @@ export class ModbusSlaveConfigComponent implements ControlValueAccessor, Validat } private updateEnablingByProtocol(type: ModbusProtocolType): void { - if (type === ModbusProtocolType.Serial) { - if (this.slaveConfigFormGroup.get('sendDataToThingsBoard').value) { - this.serialSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); - } - this.tcpUdpSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({emitEvent: false})); - } else { - this.serialSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({emitEvent: false})); - if (this.slaveConfigFormGroup.get('sendDataToThingsBoard').value) { - this.tcpUdpSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); - } + const enableKeys = type === ModbusProtocolType.Serial ? this.serialSpecificControlKeys : this.tcpUdpSpecificControlKeys; + const disableKeys = type === ModbusProtocolType.Serial ? this.tcpUdpSpecificControlKeys : this.serialSpecificControlKeys; + + if (this.isSlaveEnabled) { + enableKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({ emitEvent: false })); } - }; + + disableKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({ emitEvent: false })); + } private updateSlaveConfig(slaveConfig: ModbusSlave): void { const { + type = ModbusProtocolType.TCP, + method = ModbusMethodType.RTU, + unitId = 0, + deviceName = '', + deviceType = '', + pollPeriod = 5000, + sendDataToThingsBoard = false, + byteOrder = ModbusOrderType.BIG, + security = {}, + identity = { + vendorName: '', + productCode: '', + vendorUrl: '', + productName: '', + modelName: '', + }, + values = {} as ModbusRegisterValues, + baudrate = this.modbusBaudrates[0], + host = '', + port = null, + } = slaveConfig; + + const slaveState: ModbusSlave = { type, method, unitId, deviceName, deviceType, pollPeriod, - sendDataToThingsBoard, + sendDataToThingsBoard: !!sendDataToThingsBoard, byteOrder, security, identity, values, baudrate, - host, - port, - } = slaveConfig; - let slaveState: ModbusSlave = { - host: host ?? '', - type: type ?? ModbusProtocolType.TCP, - method: method ?? ModbusMethodType.RTU, - unitId: unitId ?? 0, - deviceName: deviceName ?? '', - deviceType: deviceType ?? '', - pollPeriod: pollPeriod ?? 5000, - sendDataToThingsBoard: !!sendDataToThingsBoard, - byteOrder: byteOrder ?? ModbusOrderType.BIG, - security: security ?? {}, - identity: identity ?? { - vendorName: '', - productCode: '', - vendorUrl: '', - productName: '', - modelName: '', - }, - values: values ?? {} as ModbusRegisterValues, - port: port ?? null, - baudrate: baudrate ?? this.modbusBaudrates[0], + host: type === ModbusProtocolType.Serial ? '' : host, + port: type === ModbusProtocolType.Serial ? null : port, + serialPort: (type === ModbusProtocolType.Serial ? port : '') as string, }; - if (slaveConfig.type === ModbusProtocolType.Serial) { - slaveState = { ...slaveState, serialPort: port, host: '', port: null } as ModbusSlave; - } else { - slaveState = { ...slaveState, serialPort: '' } as ModbusSlave; - } - this.slaveConfigFormGroup.setValue(slaveState, {emitEvent: false}); + + this.slaveConfigFormGroup.setValue(slaveState, { emitEvent: false }); } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html index 60ef25f875..31d2202fcb 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.html @@ -105,10 +105,8 @@ warning diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts index 8c6fb87e11..aae327ee6f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-slave-dialog/modbus-slave-dialog.component.ts @@ -17,14 +17,13 @@ import { ChangeDetectionStrategy, Component, forwardRef, Inject, OnDestroy } from '@angular/core'; import { FormBuilder, + FormControl, NG_VALIDATORS, NG_VALUE_ACCESSOR, - UntypedFormControl, UntypedFormGroup, Validators, } from '@angular/forms'; import { - MappingInfo, ModbusBaudrates, ModbusByteSizes, ModbusMethodLabelsMap, @@ -35,6 +34,7 @@ import { ModbusProtocolLabelsMap, ModbusProtocolType, ModbusSerialMethodType, + ModbusSlaveInfo, noLeadTrailSpacesRegex, PortLimits, SlaveConfig, @@ -80,15 +80,15 @@ import { isEqual } from '@core/utils'; styles: [` :host { .slaves-config-container { - width: 900px; - } + width: 80vw; + max-width: 900px; } } `], }) export class ModbusSlaveDialogComponent extends DialogComponent implements OnDestroy { slaveConfigFormGroup: UntypedFormGroup; - showSecurityControl: UntypedFormControl; + showSecurityControl: FormControl; portLimits = PortLimits; readonly modbusProtocolTypes = Object.values(ModbusProtocolType); @@ -104,8 +104,9 @@ export class ModbusSlaveDialogComponent extends DialogComponent(); @@ -113,7 +114,7 @@ export class ModbusSlaveDialogComponent extends DialogComponent, protected router: Router, - @Inject(MAT_DIALOG_DATA) public data: MappingInfo, + @Inject(MAT_DIALOG_DATA) public data: ModbusSlaveInfo, public dialogRef: MatDialogRef, ) { super(store, router, dialogRef); @@ -121,42 +122,38 @@ export class ModbusSlaveDialogComponent extends DialogComponent { - this.updateControlsEnabling(type); - }); + this.slaveConfigFormGroup.get('type').valueChanges + .pipe(takeUntil(this.destroy$)) + .subscribe(type => this.updateControlsEnabling(type)); } private updateControlsEnabling(type: ModbusProtocolType): void { - if (type === ModbusProtocolType.Serial) { - this.serialSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); - this.tcpUdpSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({emitEvent: false})); - } else { - this.serialSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({emitEvent: false})); - this.tcpUdpSpecificControlKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({emitEvent: false})); - } - }; + const [enableKeys, disableKeys] = type === ModbusProtocolType.Serial + ? [this.serialSpecificControlKeys, this.tcpUdpSpecificControlKeys] + : [this.tcpUdpSpecificControlKeys, this.serialSpecificControlKeys]; + + enableKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.enable({ emitEvent: false })); + disableKeys.forEach(key => this.slaveConfigFormGroup.get(key)?.disable({ emitEvent: false })); + + this.updateSecurityEnabling(this.showSecurityControl.value); + } private observeShowSecurity(): void { - this.showSecurityControl.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => { - if (value) { - this.slaveConfigFormGroup.get('security').enable({emitEvent: false}); - } else { - this.slaveConfigFormGroup.get('security').disable({emitEvent: false}); - } - }); + this.showSecurityControl.valueChanges + .pipe(takeUntil(this.destroy$)) + .subscribe(value => this.updateSecurityEnabling(value)); + } + + private updateSecurityEnabling(isEnabled: boolean): void { + if (isEnabled) { + this.slaveConfigFormGroup.get('security').enable({emitEvent: false}); + } else { + this.slaveConfigFormGroup.get('security').disable({emitEvent: false}); + } } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts index 0e57d06d85..e111fee7b1 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/connectors-configuration/modbus/modbus-values/modbus-values.component.ts @@ -42,6 +42,7 @@ import { ModbusRegisterTranslationsMap, ModbusRegisterType, ModbusRegisterValues, + ModbusValue, ModbusValueKey, ModbusValues, ModbusValuesState, @@ -103,7 +104,7 @@ export class ModbusValuesComponent implements ControlValueAccessor, Validator, O ModbusValueKey = ModbusValueKey; valuesFormGroup: FormGroup; - private onChange: (value: string) => void; + private onChange: (value: ModbusValuesState) => void; private onTouched: () => void; private destroy$ = new Subject(); @@ -125,7 +126,7 @@ export class ModbusValuesComponent implements ControlValueAccessor, Validator, O this.destroy$.complete(); } - registerOnChange(fn: (value: string) => void): void { + registerOnChange(fn: (value: ModbusValuesState) => void): void { this.onChange = fn; } @@ -135,15 +136,15 @@ export class ModbusValuesComponent implements ControlValueAccessor, Validator, O writeValue(values: ModbusValuesState): void { if (this.singleMode) { - this.valuesFormGroup.setValue(this.getSingleRegisterState(values as ModbusValues), {emitEvent: false}); + this.valuesFormGroup.setValue(this.getSingleRegisterState(values as ModbusValues), { emitEvent: false }); } else { - const registers = values as ModbusRegisterValues; + const { holding_registers, coils_initializer, input_registers, discrete_inputs } = values as ModbusRegisterValues; this.valuesFormGroup.setValue({ - holding_registers: this.getSingleRegisterState(registers.holding_registers), - coils_initializer: this.getSingleRegisterState(registers.coils_initializer), - input_registers: this.getSingleRegisterState(registers.input_registers), - discrete_inputs: this.getSingleRegisterState(registers.discrete_inputs), - }, {emitEvent: false}); + holding_registers: this.getSingleRegisterState(holding_registers), + coils_initializer: this.getSingleRegisterState(coils_initializer), + input_registers: this.getSingleRegisterState(input_registers), + discrete_inputs: this.getSingleRegisterState(discrete_inputs), + }, { emitEvent: false }); } this.cdr.markForCheck(); } @@ -159,69 +160,63 @@ export class ModbusValuesComponent implements ControlValueAccessor, Validator, O this.cdr.markForCheck(); } - getValueGroup(valueKey: ModbusValueKey, register?: ModbusRegisterType) { + getValueGroup(valueKey: ModbusValueKey, register?: ModbusRegisterType): FormGroup { return register ? this.valuesFormGroup.get(register).get(valueKey).value : this.valuesFormGroup.get(valueKey).value; } manageKeys($event: Event, matButton: MatButton, keysType: ModbusValueKey, register?: ModbusRegisterType): void { - if ($event) { - $event.stopPropagation(); - } + $event.stopPropagation(); const trigger = matButton._elementRef.nativeElement; if (this.popoverService.hasPopover(trigger)) { this.popoverService.hidePopover(trigger); - } else { - const group = this.valuesFormGroup; - - const keysControl = register ? group.get(register).get(keysType) : group.get(keysType); - const ctx = { - values: keysControl.value, - isMaster: !this.singleMode, - keysType, - panelTitle: ModbusKeysPanelTitleTranslationsMap.get(keysType), - addKeyTitle: ModbusKeysAddKeyTranslationsMap.get(keysType), - deleteKeyTitle: ModbusKeysDeleteKeyTranslationsMap.get(keysType), - noKeysText: ModbusKeysNoKeysTextTranslationsMap.get(keysType) - }; - const dataKeysPanelPopover = this.popoverService.displayPopover( - trigger, - this.renderer, - this.viewContainerRef, - ModbusDataKeysPanelComponent, - 'leftBottom', - false, - null, - ctx, - {}, - {}, - {}, - true - ); - dataKeysPanelPopover.tbComponentRef.instance.popover = dataKeysPanelPopover; - dataKeysPanelPopover.tbComponentRef.instance.keysDataApplied.pipe(takeUntil(this.destroy$)).subscribe((keysData) => { - dataKeysPanelPopover.hide(); - keysControl.patchValue(keysData); - keysControl.markAsDirty(); - this.cdr.markForCheck(); - }); + return; } + + const keysControl = this.getValueGroup(keysType, register); + const ctx = { + values: keysControl.value, + isMaster: !this.singleMode, + keysType, + panelTitle: ModbusKeysPanelTitleTranslationsMap.get(keysType), + addKeyTitle: ModbusKeysAddKeyTranslationsMap.get(keysType), + deleteKeyTitle: ModbusKeysDeleteKeyTranslationsMap.get(keysType), + noKeysText: ModbusKeysNoKeysTextTranslationsMap.get(keysType) + }; + const dataKeysPanelPopover = this.popoverService.displayPopover( + trigger, + this.renderer, + this.viewContainerRef, + ModbusDataKeysPanelComponent, + 'leftBottom', + false, + null, + ctx, + {}, + {}, + {}, + true + ); + dataKeysPanelPopover.tbComponentRef.instance.popover = dataKeysPanelPopover; + dataKeysPanelPopover.tbComponentRef.instance.keysDataApplied.pipe(takeUntil(this.destroy$)).subscribe((keysData: ModbusValue[]) => { + dataKeysPanelPopover.hide(); + keysControl.patchValue(keysData); + keysControl.markAsDirty(); + this.cdr.markForCheck(); + }); } private initializeValuesFormGroup(): void { + const getValuesFormGroup = () => this.fb.group(this.modbusValueKeys.reduce((acc, key) => { + acc[key] = this.fb.control([[], []]); + return acc; + }, {})); + if (this.singleMode) { - this.valuesFormGroup = this.fb.group(this.modbusValueKeys.reduce((acc, key) => { - acc[key] = this.fb.control([[], []]); - return acc; - }, {})); + this.valuesFormGroup = getValuesFormGroup(); } else { this.valuesFormGroup = this.fb.group( this.modbusRegisterTypes.reduce((registersAcc, register) => { - - registersAcc[register] = this.fb.group(this.modbusValueKeys.reduce((acc, key) => { - acc[key] = this.fb.control([[], []]); - return acc; - }, {})); - + registersAcc[register] = getValuesFormGroup(); return registersAcc; }, {}) ); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts index 2db6d9d2fe..3bdb67069a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/gateway/gateway-widget.models.ts @@ -485,6 +485,11 @@ export interface MappingInfo { buttonTitle: string; } +export interface ModbusSlaveInfo { + value: SlaveConfig; + buttonTitle: string; +} + export enum ConnectorConfigurationModes { BASIC = 'basic', ADVANCED = 'advanced' @@ -852,24 +857,6 @@ export enum ModbusObjectCountByDataType { '64float' = 4, } -export enum ModbusValueField { - Tag = 'tag', - Type = 'type', - ObjectsCount = 'objectsCount', - Address = 'address', - Value = 'value', -} - -export const ModbusFieldsTranslationsMap = new Map( - [ - [ModbusValueField.Tag, 'gateway.tag'], - [ModbusValueField.Type, 'gateway.type'], - [ModbusValueField.ObjectsCount, 'gateway.objects_count'], - [ModbusValueField.Address, 'gateway.address'], - [ModbusValueField.Value, 'gateway.value'] - ] -); - export enum ModbusValueKey { ATTRIBUTES = 'attributes', TIMESERIES = 'timeseries', @@ -946,7 +933,7 @@ export interface SlaveConfig { pollPeriod: number; unitId: number; deviceName: string; - deviceType?: string; + deviceType: string; sendDataOnlyOnChange: boolean; connectAttemptTimeMs: number; connectAttemptCount: number; @@ -959,7 +946,7 @@ export interface SlaveConfig { baudrate?: number; stopbits?: number; bytesize?: number; - parity?: string; + parity?: ModbusParity; strict?: boolean; } diff --git a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts index 1e4093c22c..504f98420e 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget-components.module.ts @@ -208,25 +208,26 @@ import { LabelCardWidgetComponent, LabelValueCardWidgetComponent, UnreadNotificationWidgetComponent, - NotificationTypeFilterPanelComponent], - imports: [ - CommonModule, - SharedModule, - RpcWidgetsModule, - HomePageWidgetsModule, - SharedHomeComponentsModule, - RestConnectorSecurityComponent, - GatewayHelpLinkPipe, - BrokerConfigControlComponent, - WorkersConfigControlComponent, - OpcServerConfigComponent, - MqttBasicConfigComponent, - MappingTableComponent, - OpcUaBasicConfigComponent, - KeyValueIsNotEmptyPipe, - ModbusBasicConfigComponent, - EllipsisChipListDirective, - ], + NotificationTypeFilterPanelComponent + ], + imports: [ + CommonModule, + SharedModule, + RpcWidgetsModule, + HomePageWidgetsModule, + SharedHomeComponentsModule, + RestConnectorSecurityComponent, + GatewayHelpLinkPipe, + BrokerConfigControlComponent, + WorkersConfigControlComponent, + OpcServerConfigComponent, + MqttBasicConfigComponent, + MappingTableComponent, + OpcUaBasicConfigComponent, + KeyValueIsNotEmptyPipe, + ModbusBasicConfigComponent, + EllipsisChipListDirective, + ], exports: [ EntitiesTableWidgetComponent, AlarmsTableWidgetComponent, diff --git a/ui-ngx/src/app/modules/home/pipes/gateway-port-tooltip.pipe.ts b/ui-ngx/src/app/modules/home/pipes/gateway-port-tooltip.pipe.ts index 3981499a26..fcf5766c05 100644 --- a/ui-ngx/src/app/modules/home/pipes/gateway-port-tooltip.pipe.ts +++ b/ui-ngx/src/app/modules/home/pipes/gateway-port-tooltip.pipe.ts @@ -30,12 +30,12 @@ export class GatewayPortTooltipPipe implements PipeTransform { transform(portControl: AbstractControl): string { if (portControl.hasError('required')) { return this.translate.instant('gateway.port-required'); - } else if ( - portControl.hasError('min') || - portControl.hasError('max') - ) { - return this.translate.instant('gateway.port-limits-error', - {min: PortLimits.MIN, max: PortLimits.MAX}); + } + if (portControl.hasError('min') || portControl.hasError('max')) { + return this.translate.instant('gateway.port-limits-error', { + min: PortLimits.MIN, + max: PortLimits.MAX, + }); } return ''; } diff --git a/ui-ngx/src/app/shared/directives/ellipsis-chip-list.directive.ts b/ui-ngx/src/app/shared/directives/ellipsis-chip-list.directive.ts index bb2847aeee..c320a2f78a 100644 --- a/ui-ngx/src/app/shared/directives/ellipsis-chip-list.directive.ts +++ b/ui-ngx/src/app/shared/directives/ellipsis-chip-list.directive.ts @@ -61,8 +61,11 @@ export class EllipsisChipListDirective implements OnDestroy { ).subscribe(() => { this.adjustChips(); }); + this.observeIntersection(); + } - this.intersectionObserver = new IntersectionObserver((entries) => { + private observeIntersection(): void { + this.intersectionObserver = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { this.adjustChips(); diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index fb8f695619..967e6a0122 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2756,6 +2756,7 @@ }, "gateway": { "address": "Address", + "address-required": "Address required", "add-entry": "Add configuration", "add-attribute": "Add attribute", "add-attribute-update": "Add attribute update", diff --git a/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json b/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json index fee4e745d6..c84a2278b9 100644 --- a/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json +++ b/ui-ngx/src/assets/metadata/connector-default-configs/modbus.json @@ -16,6 +16,7 @@ "pollPeriod": 5000, "unitId": 1, "deviceName": "Temp Sensor", + "deviceType": "default", "sendDataOnlyOnChange": true, "connectAttemptTimeMs": 5000, "connectAttemptCount": 5,