committed by
GitHub
7 changed files with 249 additions and 66 deletions
@ -0,0 +1,65 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2024 The Thingsboard Authors |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
|
|||
--> |
|||
<div class="tb-form-row space-between same-padding tb-flex column" [formGroup]="securityFormGroup"> |
|||
<div class="tb-flex row space-between align-center no-gap fill-width"> |
|||
<div class="fields-label" translate>gateway.security</div> |
|||
<tb-toggle-select formControlName="type" appearance="fill"> |
|||
<tb-toggle-option *ngFor="let type of securityTypes" [value]="type"> |
|||
{{ SecurityTypeTranslationsMap.get(type) | translate }} |
|||
</tb-toggle-option> |
|||
</tb-toggle-select> |
|||
</div> |
|||
<ng-container *ngIf="securityFormGroup.get('type').value === BrokerSecurityType.BASIC"> |
|||
<div class="tb-form-row space-between tb-flex fill-width"> |
|||
<div class="fixed-title-width" translate>gateway.username</div> |
|||
<div class="tb-flex no-gap"> |
|||
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic"> |
|||
<input matInput name="value" formControlName="username" placeholder="{{ 'gateway.set' | translate }}"/> |
|||
<mat-icon matSuffix |
|||
matTooltipPosition="above" |
|||
matTooltipClass="tb-error-tooltip" |
|||
[matTooltip]="('gateway.username-required') | translate" |
|||
*ngIf="securityFormGroup.get('username').hasError('required') && securityFormGroup.get('username').touched" |
|||
class="tb-error"> |
|||
warning |
|||
</mat-icon> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
<div class="tb-form-row space-between tb-flex fill-width"> |
|||
<div class="fixed-title-width" translate>gateway.password</div> |
|||
<div class="tb-flex no-gap"> |
|||
<mat-form-field class="tb-flex no-gap" appearance="outline" subscriptSizing="dynamic"> |
|||
<input matInput type="password" name="value" formControlName="password" placeholder="{{ 'gateway.set' | translate }}"/> |
|||
<mat-icon matSuffix |
|||
matTooltipPosition="above" |
|||
matTooltipClass="tb-error-tooltip" |
|||
[matTooltip]="('gateway.password-required') | translate" |
|||
*ngIf="securityFormGroup.get('password').hasError('required') |
|||
&& securityFormGroup.get('password').touched" |
|||
class="tb-error"> |
|||
warning |
|||
</mat-icon> |
|||
<div [class.hide-toggle]="securityFormGroup.get('password').hasError('required')" class="tb-flex no-gap align-center fill-height" matSuffix> |
|||
<tb-toggle-password class="tb-flex align-center fill-height"></tb-toggle-password> |
|||
</div> |
|||
</mat-form-field> |
|||
</div> |
|||
</div> |
|||
</ng-container> |
|||
</div> |
|||
@ -0,0 +1,29 @@ |
|||
/** |
|||
* Copyright © 2016-2024 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0 |
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
:host { |
|||
width: 100%; |
|||
height: 100%; |
|||
display: block; |
|||
margin-bottom: 10px; |
|||
|
|||
.fields-label { |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.hide-toggle { |
|||
display: none; |
|||
} |
|||
} |
|||
@ -0,0 +1,132 @@ |
|||
///
|
|||
/// Copyright © 2016-2024 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { |
|||
ChangeDetectionStrategy, |
|||
Component, |
|||
forwardRef, |
|||
OnDestroy, |
|||
} from '@angular/core'; |
|||
import { Subject } from 'rxjs'; |
|||
import { |
|||
ControlValueAccessor, |
|||
FormBuilder, |
|||
NG_VALIDATORS, |
|||
NG_VALUE_ACCESSOR, |
|||
UntypedFormGroup, |
|||
ValidationErrors, |
|||
Validator, |
|||
Validators |
|||
} from '@angular/forms'; |
|||
import { takeUntil } from 'rxjs/operators'; |
|||
import { |
|||
noLeadTrailSpacesRegex, |
|||
RestSecurityType, |
|||
RestSecurityTypeTranslationsMap |
|||
} from '@home/components/widget/lib/gateway/gateway-widget.models'; |
|||
import { SharedModule } from '@shared/shared.module'; |
|||
import { CommonModule } from '@angular/common'; |
|||
|
|||
@Component({ |
|||
selector: 'tb-rest-connector-security', |
|||
templateUrl: './rest-connector-security.component.html', |
|||
styleUrls: ['./rest-connector-security.component.scss'], |
|||
changeDetection: ChangeDetectionStrategy.OnPush, |
|||
providers: [ |
|||
{ |
|||
provide: NG_VALUE_ACCESSOR, |
|||
useExisting: forwardRef(() => RestConnectorSecurityComponent), |
|||
multi: true |
|||
}, |
|||
{ |
|||
provide: NG_VALIDATORS, |
|||
useExisting: forwardRef(() => RestConnectorSecurityComponent), |
|||
multi: true |
|||
} |
|||
], |
|||
standalone: true, |
|||
imports: [ |
|||
SharedModule, |
|||
CommonModule, |
|||
] |
|||
}) |
|||
export class RestConnectorSecurityComponent implements ControlValueAccessor, Validator, OnDestroy { |
|||
BrokerSecurityType = RestSecurityType; |
|||
securityTypes: RestSecurityType[] = Object.values(RestSecurityType); |
|||
SecurityTypeTranslationsMap = RestSecurityTypeTranslationsMap; |
|||
securityFormGroup: UntypedFormGroup; |
|||
|
|||
private destroy$ = new Subject<void>(); |
|||
private propagateChange = (_: any) => {}; |
|||
|
|||
constructor(private fb: FormBuilder) { |
|||
this.securityFormGroup = this.fb.group({ |
|||
type: [RestSecurityType.ANONYMOUS, []], |
|||
username: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], |
|||
password: ['', [Validators.required, Validators.pattern(noLeadTrailSpacesRegex)]], |
|||
}); |
|||
this.observeSecurityForm(); |
|||
} |
|||
|
|||
ngOnDestroy(): void { |
|||
this.destroy$.next(); |
|||
this.destroy$.complete(); |
|||
} |
|||
|
|||
registerOnChange(fn: any): void { |
|||
this.propagateChange = fn; |
|||
} |
|||
|
|||
registerOnTouched(fn: any): void {} |
|||
|
|||
writeValue(deviceInfo: any): void { |
|||
if (!deviceInfo.type) { |
|||
deviceInfo.type = RestSecurityType.ANONYMOUS; |
|||
} |
|||
this.securityFormGroup.reset(deviceInfo); |
|||
this.updateView(deviceInfo); |
|||
} |
|||
|
|||
validate(): ValidationErrors | null { |
|||
return this.securityFormGroup.valid ? null : { |
|||
securityForm: { valid: false } |
|||
}; |
|||
} |
|||
|
|||
private updateView(value: any): void { |
|||
this.propagateChange(value); |
|||
} |
|||
|
|||
private updateValidators(type: RestSecurityType): void { |
|||
if (type === RestSecurityType.BASIC) { |
|||
this.securityFormGroup.get('username').enable({emitEvent: false}); |
|||
this.securityFormGroup.get('password').enable({emitEvent: false}); |
|||
} else { |
|||
this.securityFormGroup.get('username').disable({emitEvent: false}); |
|||
this.securityFormGroup.get('password').disable({emitEvent: false}); |
|||
} |
|||
} |
|||
|
|||
private observeSecurityForm(): void { |
|||
this.securityFormGroup.valueChanges |
|||
.pipe(takeUntil(this.destroy$)) |
|||
.subscribe(value => this.updateView(value)); |
|||
|
|||
this.securityFormGroup.get('type').valueChanges |
|||
.pipe(takeUntil(this.destroy$)) |
|||
.subscribe(type => this.updateValidators(type)); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue