UI: add phone input with country flags for sms authenticator

This commit is contained in:
fe-dev 2022-06-07 13:07:57 +03:00
parent 5135ad672a
commit c2c59114db
5 changed files with 12 additions and 29 deletions

View File

@ -37,20 +37,7 @@
<form [formGroup]="smsConfigForm" (ngSubmit)="nextStep()"> <form [formGroup]="smsConfigForm" (ngSubmit)="nextStep()">
<p class="mat-body step-description input" translate>security.2fa.dialog.sms-step-description</p> <p class="mat-body step-description input" translate>security.2fa.dialog.sms-step-description</p>
<div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="8px"> <div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="8px">
<mat-form-field fxFlex class="mat-block input-container" floatLabel="always" hideRequiredMarker> <tb-phone-input fxFlex formControlName="phone" [floatLabel]="'never'"></tb-phone-input>
<mat-label></mat-label>
<input type="tel" required
[pattern]="phoneNumberPattern"
matInput formControlName="phone"
placeholder="{{ 'security.2fa.dialog.sms-step-label' | translate }}">
<mat-error *ngIf="smsConfigForm.get('phone').hasError('required')">
{{ 'admin.number-to-required' | translate }}
</mat-error>
<mat-error *ngIf="smsConfigForm.get('phone').hasError('pattern')">
{{ 'admin.phone-number-pattern' | translate }}
</mat-error>
<mat-hint innerHTML="{{ 'admin.phone-number-hint' | translate }}"></mat-hint>
</mat-form-field>
<button mat-raised-button <button mat-raised-button
type="submit" type="submit"
color="primary" color="primary"

View File

@ -27,7 +27,7 @@
</mat-option> </mat-option>
</mat-select> </mat-select>
</div> </div>
<mat-form-field class="phone-input" [floatLabel]="showLabel"> <mat-form-field class="phone-input" [appearance]="appearance" [floatLabel]="floatLabel">
<mat-label translate>phone-input.phone-input-label</mat-label> <mat-label translate>phone-input.phone-input-label</mat-label>
<input <input
formControlName="phoneNumber" formControlName="phoneNumber"
@ -38,15 +38,13 @@
(focus)="focus()" (focus)="focus()"
autocomplete="off" autocomplete="off"
[required]="required"> [required]="required">
<mat-hint innerHTML="{{ 'phone-input.phone-input-hint' | translate: {phoneNumber: phonePlaceholder} }}"></mat-hint>
<mat-error *ngIf="phoneFormGroup.get('phoneNumber').hasError('required')"> <mat-error *ngIf="phoneFormGroup.get('phoneNumber').hasError('required')">
{{ 'phone-input.phone-input-required' | translate }} {{ 'phone-input.phone-input-required' | translate }}
</mat-error> </mat-error>
<mat-error *ngIf="phoneFormGroup.get('phoneNumber').hasError('invalidPhoneNumber')"> <mat-error *ngIf="phoneFormGroup.get('phoneNumber').hasError('invalidPhoneNumber')">
{{ 'phone-input.phone-input-validation' | translate }} {{ 'phone-input.phone-input-validation' | translate }}
</mat-error> </mat-error>
<mat-error *ngIf="phoneFormGroup.get('phoneNumber').hasError('pattern')">
{{ 'phone-input.phone-input-pattern' | translate }}
</mat-error>
</mat-form-field> </mat-form-field>
</div> </div>
</form> </form>

View File

@ -21,6 +21,7 @@
.phone-input { .phone-input {
width: 100%; width: 100%;
max-width: 290px;
} }
} }

View File

@ -33,6 +33,7 @@ import examples from 'libphonenumber-js/examples.mobile.json';
import { CountryCode, getExampleNumber, parsePhoneNumberFromString } from 'libphonenumber-js'; import { CountryCode, getExampleNumber, parsePhoneNumberFromString } from 'libphonenumber-js';
import { phoneNumberPattern } from '@shared/models/settings.models'; import { phoneNumberPattern } from '@shared/models/settings.models';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field/form-field';
@Component({ @Component({
selector: 'tb-phone-input', selector: 'tb-phone-input',
@ -58,15 +59,8 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
@Input() defaultCountry: CountryCode = 'US'; @Input() defaultCountry: CountryCode = 'US';
@Input() enableFlagsSelect = true; @Input() enableFlagsSelect = true;
@Input() required = true; @Input() required = true;
@Input() floatLabel: FloatLabelType = 'always';
private floatLabel = 'always'; @Input() appearance: MatFormFieldAppearance = 'legacy';
get showLabel(): string {
return this.floatLabel;
}
@Input()
set showLabel(value) {
this.floatLabel = value ? 'always' : 'never';
}
allCountries: Array<Country> = []; allCountries: Array<Country> = [];
phonePlaceholder: string; phonePlaceholder: string;
@ -134,6 +128,8 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
focus() { focus() {
const phoneNumber = this.phoneFormGroup.get('phoneNumber'); const phoneNumber = this.phoneFormGroup.get('phoneNumber');
this.phoneFormGroup.markAsPristine();
this.phoneFormGroup.markAsUntouched();
if (!phoneNumber.value) { if (!phoneNumber.value) {
phoneNumber.patchValue(this.countryCallingCode); phoneNumber.patchValue(this.countryCallingCode);
} }
@ -220,7 +216,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida
private updateModel() { private updateModel() {
const phoneNumber = this.phoneFormGroup.get('phoneNumber'); const phoneNumber = this.phoneFormGroup.get('phoneNumber');
if (phoneNumber.valid && this.modelValue !== phoneNumber.value) { if (phoneNumber.valid && phoneNumber.value) {
this.modelValue = phoneNumber.value; this.modelValue = phoneNumber.value;
this.propagateChange(this.modelValue); this.propagateChange(this.modelValue);
} else { } else {

View File

@ -4435,7 +4435,8 @@
"phone-input-label": "Phone number", "phone-input-label": "Phone number",
"phone-input-required": "Phone number is required", "phone-input-required": "Phone number is required",
"phone-input-validation": "Phone number is invalid or not possible", "phone-input-validation": "Phone number is invalid or not possible",
"phone-input-pattern": "Invalid phone number. Should be in E.164 format, ex. {{phoneNumber}}" "phone-input-pattern": "Invalid phone number. Should be in E.164 format, ex. {{phoneNumber}}",
"phone-input-hint": "Phone Number in E.164 format, ex. {{phoneNumber}}"
}, },
"custom": { "custom": {
"widget-action": { "widget-action": {