UI: Added action copy and generate for device credentials

This commit is contained in:
Artem Dzhereleiko 2023-05-03 13:52:22 +03:00
parent 15ce59b64f
commit 79a0a06dcb
8 changed files with 105 additions and 6 deletions

View File

@ -19,6 +19,25 @@
<mat-form-field class="mat-block">
<mat-label translate>device.client-id</mat-label>
<input matInput formControlName="clientId">
<button type="button"
matSuffix
mat-icon-button
aria-label="Generate"
matTooltip="{{ 'device.generate-client-id' | translate }}"
matTooltipPosition="above"
(click)="generate('clientId')"
*ngIf="!deviceCredentialsMqttFormGroup.get('clientId').value">
<mat-icon>autorenew</mat-icon>
</button>
<tb-copy-button
matSuffix
inputAction
*ngIf="deviceCredentialsMqttFormGroup.get('clientId').value"
[copyText]="deviceCredentialsMqttFormGroup.get('clientId').value"
tooltipText="{{ 'device.copy-client-id' | translate }}"
tooltipPosition="above"
icon="content_copy">
</tb-copy-button>
<mat-error *ngIf="deviceCredentialsMqttFormGroup.get('clientId').hasError('pattern')">
{{ 'device.client-id-pattern' | translate }}
</mat-error>
@ -26,6 +45,25 @@
<mat-form-field class="mat-block">
<mat-label translate>device.user-name</mat-label>
<input matInput formControlName="userName" [required]="!!deviceCredentialsMqttFormGroup.get('password').value">
<button type="button"
matSuffix
mat-icon-button
aria-label="Generate"
matTooltip="{{ 'device.generate-user-name' | translate }}"
matTooltipPosition="above"
(click)="generate('userName')"
*ngIf="!deviceCredentialsMqttFormGroup.get('userName').value">
<mat-icon>autorenew</mat-icon>
</button>
<tb-copy-button
matSuffix
inputAction
*ngIf="deviceCredentialsMqttFormGroup.get('userName').value"
[copyText]="deviceCredentialsMqttFormGroup.get('userName').value"
tooltipText="{{ 'device.copy-user-name' | translate }}"
tooltipPosition="above"
icon="content_copy">
</tb-copy-button>
<mat-error *ngIf="deviceCredentialsMqttFormGroup.get('userName').hasError('required')">
{{ 'device.user-name-required' | translate }}
</mat-error>
@ -37,6 +75,25 @@
(ngModelChange)="passwordChanged()"
type="password">
<tb-toggle-password matSuffix></tb-toggle-password>
<button type="button"
matSuffix
mat-icon-button
aria-label="Generate"
matTooltip="{{ 'device.generate-password' | translate }}"
matTooltipPosition="above"
(click)="generate('password')"
*ngIf="!deviceCredentialsMqttFormGroup.get('password').value">
<mat-icon>autorenew</mat-icon>
</button>
<tb-copy-button
matSuffix
inputAction
*ngIf="deviceCredentialsMqttFormGroup.get('password').value"
[copyText]="deviceCredentialsMqttFormGroup.get('password').value"
tooltipText="{{ 'device.copy-password' | translate }}"
tooltipPosition="above"
icon="content_copy">
</tb-copy-button>
</mat-form-field>
<tb-error style="margin-top: -12px; display: block;"
[error]="deviceCredentialsMqttFormGroup.hasError('atLeastOne') ?

View File

@ -29,7 +29,7 @@ import {
import { Subject } from 'rxjs';
import { DeviceCredentialMQTTBasic } from '@shared/models/device.models';
import { takeUntil } from 'rxjs/operators';
import { isDefinedAndNotNull, isEmptyStr } from '@core/utils';
import { generateSecret, isDefinedAndNotNull, isEmptyStr } from '@core/utils';
@Component({
selector: 'tb-device-credentials-mqtt-basic',
@ -128,4 +128,8 @@ export class DeviceCredentialsMqttBasicComponent implements ControlValueAccessor
return hasAtLeastOne ? null : {atLeastOne: true};
};
}
public generate(formControlName: string) {
this.deviceCredentialsMqttFormGroup.get(formControlName).patchValue(generateSecret(12));
}
}

View File

@ -29,6 +29,15 @@
<mat-form-field class="mat-block">
<mat-label translate>device.access-token</mat-label>
<input matInput formControlName="credentialsId" required>
<tb-copy-button
matSuffix
inputAction
*ngIf="deviceCredentialsFormGroup.get('credentialsId').value"
[copyText]="deviceCredentialsFormGroup.get('credentialsId').value"
tooltipText="{{ 'device.copy-access-token' | translate }}"
tooltipPosition="above"
icon="content_copy">
</tb-copy-button>
<mat-error *ngIf="deviceCredentialsFormGroup.get('credentialsId').hasError('required')">
{{ 'device.access-token-required' | translate }}
</mat-error>
@ -41,6 +50,15 @@
<mat-form-field class="mat-block">
<mat-label translate>device.certificate-pem-format</mat-label>
<textarea matInput formControlName="credentialsValue" cols="15" rows="5" required></textarea>
<tb-copy-button
matSuffix
inputAction
*ngIf="deviceCredentialsFormGroup.get('credentialsValue').value"
[copyText]="deviceCredentialsFormGroup.get('credentialsValue').value"
tooltipText="{{ 'device.copy-certificate' | translate }}"
tooltipPosition="above"
icon="content_copy">
</tb-copy-button>
<mat-error *ngIf="deviceCredentialsFormGroup.get('credentialsValue').hasError('required')">
{{ 'device.certificate-pem-format-required' | translate }}
</mat-error>

View File

@ -95,6 +95,7 @@
<input matInput [value]="redirectURI(domainInfo)" readonly>
<tb-copy-button
matSuffix
inputAction
color="primary"
[copyText]="redirectURI(domainInfo)"
tooltipText="{{ 'admin.oauth2.copy-redirect-uri' | translate }}"
@ -106,6 +107,7 @@
<input matInput [value]="redirectURIMixed(domainInfo)" readonly>
<tb-copy-button
matSuffix
inputAction
color="primary"
[copyText]="redirectURIMixed(domainInfo)"
tooltipText="{{ 'admin.oauth2.copy-redirect-uri' | translate }}"
@ -164,6 +166,7 @@
<textarea matInput formControlName="appSecret" rows="1" required></textarea>
<tb-copy-button
matSuffix
inputAction
color="primary"
[copyText]="mobileInfo.get('appSecret').value"
tooltipText="{{ 'admin.oauth2.copy-mobile-app-secret' | translate }}"

View File

@ -17,6 +17,7 @@
-->
<button mat-icon-button
type="button"
[ngClass]="{'table-cell-action': !inputAction}"
[color]="color"
[disabled]="disabled"
[matTooltip]="matTooltipText"

View File

@ -13,20 +13,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import "../../../../theme";
:host {
.mat-mdc-icon-button{
.table-cell-action {
height: 32px;
width: 32px;
line-height: 32px;
padding: 4px;
vertical-align: middle;
.mat-icon.copied{
color: #00C851 !important;
}
}
.mat-icon.copied{
color: #00C851 !important;
}
&:hover{
.mat-icon{
color: #28567E !important;
color: $tb-primary-color !important;
}
}
}

View File

@ -19,6 +19,7 @@ import { ClipboardService } from 'ngx-clipboard';
import { TooltipPosition } from '@angular/material/tooltip';
import { TranslateService } from '@ngx-translate/core';
import { ThemePalette } from '@angular/material/core';
import { coerceBoolean } from '@shared/decorators/coerce-boolean';
@Component({
selector: 'tb-copy-button',
@ -55,6 +56,10 @@ export class CopyButtonComponent {
@Input()
color: ThemePalette;
@Input()
@coerceBoolean()
inputAction = false;
@Output()
successCopied = new EventEmitter<string>();

View File

@ -1233,6 +1233,14 @@
"access-token-invalid": "Access token length must be from 1 to 32 characters.",
"certificate-pem-format": "Certificate in PEM format",
"certificate-pem-format-required": "Certificate is required.",
"copy-access-token": "Copy Access token",
"copy-certificate": "Copy Certificate",
"copy-client-id": "Copy Client ID",
"copy-user-name": "Copy User name",
"copy-password": "Copy Password",
"generate-client-id": "Generate Client ID",
"generate-user-name": "Generate User name",
"generate-password": "Generate Password",
"lwm2m-security-config": {
"identity": "Client Identity",
"identity-required": "Client Identity is required.",