diff --git a/ui-ngx/src/app/modules/home/components/entity/contact-based.component.ts b/ui-ngx/src/app/modules/home/components/entity/contact-based.component.ts index 063de82ad2..2d08fd9f50 100644 --- a/ui-ngx/src/app/modules/home/components/entity/contact-based.component.ts +++ b/ui-ngx/src/app/modules/home/components/entity/contact-based.component.ts @@ -19,10 +19,10 @@ import { AppState } from '@core/core.state'; import { UntypedFormBuilder, UntypedFormGroup, ValidatorFn, Validators } from '@angular/forms'; import { ContactBased } from '@shared/models/contact-based.model'; import { AfterViewInit, ChangeDetectorRef, Directive } from '@angular/core'; -import { POSTAL_CODE_PATTERNS } from '@home/models/contact.models'; import { HasId } from '@shared/models/base-data'; import { EntityComponent } from './entity.component'; import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; +import { CountryData } from '@shared/models/country.models'; @Directive() export abstract class ContactBasedComponent> extends EntityComponent implements AfterViewInit { @@ -31,7 +31,8 @@ export abstract class ContactBasedComponent> exten protected fb: UntypedFormBuilder, protected entityValue: T, protected entitiesTableConfigValue: EntityTableConfig, - protected cd: ChangeDetectorRef) { + protected cd: ChangeDetectorRef, + protected countryData: CountryData) { super(store, fb, entityValue, entitiesTableConfigValue, cd); } @@ -75,9 +76,11 @@ export abstract class ContactBasedComponent> exten zipValidators(country: string): ValidatorFn[] { const zipValidators = []; - if (country && POSTAL_CODE_PATTERNS[country]) { - const postalCodePattern = POSTAL_CODE_PATTERNS[country]; - zipValidators.push(Validators.pattern(postalCodePattern)); + if (country) { + const postCodePattern = this.countryData.allCountries.find(item => item.name === country)?.postCodePattern; + if (postCodePattern) { + zipValidators.push(Validators.pattern(postCodePattern)); + } } return zipValidators; } diff --git a/ui-ngx/src/app/modules/home/models/contact.models.ts b/ui-ngx/src/app/modules/home/models/contact.models.ts deleted file mode 100644 index 41ebecc865..0000000000 --- a/ui-ngx/src/app/modules/home/models/contact.models.ts +++ /dev/null @@ -1,291 +0,0 @@ -/// -/// 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. -/// - -export const COUNTRIES = [ - 'Afghanistan', - 'Åland Islands', - 'Albania', - 'Algeria', - 'American Samoa', - 'Andorra', - 'Angola', - 'Anguilla', - 'Antarctica', - 'Antigua and Barbuda', - 'Argentina', - 'Armenia', - 'Aruba', - 'Australia', - 'Austria', - 'Azerbaijan', - 'Bahamas', - 'Bahrain', - 'Bangladesh', - 'Barbados', - 'Belarus', - 'Belgium', - 'Belize', - 'Benin', - 'Bermuda', - 'Bhutan', - 'Bolivia', - 'Bonaire, Sint Eustatius and Saba', - 'Bosnia and Herzegovina', - 'Botswana', - 'Bouvet Island', - 'Brazil', - 'British Indian Ocean Territory', - 'Brunei Darussalam', - 'Bulgaria', - 'Burkina Faso', - 'Burundi', - 'Cambodia', - 'Cameroon', - 'Canada', - 'Cape Verde', - 'Cayman Islands', - 'Central African Republic', - 'Chad', - 'Chile', - 'China', - 'Christmas Island', - 'Cocos (Keeling) Islands', - 'Colombia', - 'Comoros', - 'Congo', - 'Congo, The Democratic Republic of the', - 'Cook Islands', - 'Costa Rica', - 'Côte d\'Ivoire', - 'Croatia', - 'Cuba', - 'Curaçao', - 'Cyprus', - 'Czech Republic', - 'Denmark', - 'Djibouti', - 'Dominica', - 'Dominican Republic', - 'Ecuador', - 'Egypt', - 'El Salvador', - 'Equatorial Guinea', - 'Eritrea', - 'Estonia', - 'Ethiopia', - 'Falkland Islands (Malvinas)', - 'Faroe Islands', - 'Fiji', - 'Finland', - 'France', - 'French Guiana', - 'French Polynesia', - 'French Southern Territories', - 'Gabon', - 'Gambia', - 'Georgia', - 'Germany', - 'Ghana', - 'Gibraltar', - 'Greece', - 'Greenland', - 'Grenada', - 'Guadeloupe', - 'Guam', - 'Guatemala', - 'Guernsey', - 'Guinea', - 'Guinea-Bissau', - 'Guyana', - 'Haiti', - 'Heard Island and McDonald Islands', - 'Holy See (Vatican City State)', - 'Honduras', - 'Hong Kong', - 'Hungary', - 'Iceland', - 'India', - 'Indonesia', - 'Iran, Islamic Republic of', - 'Iraq', - 'Ireland', - 'Isle of Man', - 'Israel', - 'Italy', - 'Jamaica', - 'Japan', - 'Jersey', - 'Jordan', - 'Kazakhstan', - 'Kenya', - 'Kiribati', - 'Korea, Democratic People\'s Republic of', - 'Korea, Republic of', - 'Kuwait', - 'Kyrgyzstan', - 'Lao People\'s Democratic Republic', - 'Latvia', - 'Lebanon', - 'Lesotho', - 'Liberia', - 'Libya', - 'Liechtenstein', - 'Lithuania', - 'Luxembourg', - 'Macao', - 'Macedonia, Republic Of', - 'Madagascar', - 'Malawi', - 'Malaysia', - 'Maldives', - 'Mali', - 'Malta', - 'Marshall Islands', - 'Martinique', - 'Mauritania', - 'Mauritius', - 'Mayotte', - 'Mexico', - 'Micronesia, Federated States of', - 'Moldova, Republic of', - 'Monaco', - 'Mongolia', - 'Montenegro', - 'Montserrat', - 'Morocco', - 'Mozambique', - 'Myanmar', - 'Namibia', - 'Nauru', - 'Nepal', - 'Netherlands', - 'New Caledonia', - 'New Zealand', - 'Nicaragua', - 'Niger', - 'Nigeria', - 'Niue', - 'Norfolk Island', - 'Northern Mariana Islands', - 'Norway', - 'Oman', - 'Pakistan', - 'Palau', - 'Palestinian Territory, Occupied', - 'Panama', - 'Papua New Guinea', - 'Paraguay', - 'Peru', - 'Philippines', - 'Pitcairn', - 'Poland', - 'Portugal', - 'Puerto Rico', - 'Qatar', - 'Reunion', - 'Romania', - 'Russian Federation', - 'Rwanda', - 'Saint Barthélemy', - 'Saint Helena, Ascension and Tristan da Cunha', - 'Saint Kitts and Nevis', - 'Saint Lucia', - 'Saint Martin (French Part)', - 'Saint Pierre and Miquelon', - 'Saint Vincent and the Grenadines', - 'Samoa', - 'San Marino', - 'Sao Tome and Principe', - 'Saudi Arabia', - 'Senegal', - 'Serbia', - 'Seychelles', - 'Sierra Leone', - 'Singapore', - 'Sint Maarten (Dutch Part)', - 'Slovakia', - 'Slovenia', - 'Solomon Islands', - 'Somalia', - 'South Africa', - 'South Georgia and the South Sandwich Islands', - 'South Sudan', - 'Spain', - 'Sri Lanka', - 'Sudan', - 'Suriname', - 'Svalbard and Jan Mayen', - 'Swaziland', - 'Sweden', - 'Switzerland', - 'Syrian Arab Republic', - 'Taiwan', - 'Tajikistan', - 'Tanzania, United Republic of', - 'Thailand', - 'Timor-Leste', - 'Togo', - 'Tokelau', - 'Tonga', - 'Trinidad and Tobago', - 'Tunisia', - 'Turkey', - 'Turkmenistan', - 'Turks and Caicos Islands', - 'Tuvalu', - 'Uganda', - 'Ukraine', - 'United Arab Emirates', - 'United Kingdom', - 'United States', - 'United States Minor Outlying Islands', - 'Uruguay', - 'Uzbekistan', - 'Vanuatu', - 'Venezuela', - 'Viet Nam', - 'Virgin Islands, British', - 'Virgin Islands, U.S.', - 'Wallis and Futuna', - 'Western Sahara', - 'Yemen', - 'Zambia', - 'Zimbabwe' -]; - -/* eslint-disable */ -export const POSTAL_CODE_PATTERNS = { - 'United States': '(\\d{5}([\\-]\\d{4})?)', - 'Australia': '[0-9]{4}', - 'Austria': '[0-9]{4}', - 'Belgium': '[0-9]{4}', - 'Brazil': '[0-9]{5}[\\-]?[0-9]{3}', - 'Canada': '^(?!.*[DFIOQU])[A-VXY][0-9][A-Z][ -]?[0-9][A-Z][0-9]$', - 'Denmark': '[0-9]{3,4}', - 'Faroe Islands': '[0-9]{3,4}', - 'Netherlands': '[1-9][0-9]{3}\\s?[a-zA-Z]{2}', - 'Germany': '[0-9]{5}', - 'Hungary': '[0-9]{4}', - 'Italy': '[0-9]{5}', - 'Japan': '\\d{3}-\\d{4}', - 'Luxembourg': '(L\\s*(-|—|–))\\s*?[\\d]{4}', - 'Poland': '[0-9]{2}\\-[0-9]{3}', - 'Spain': '((0[1-9]|5[0-2])|[1-4][0-9])[0-9]{3}', - 'Sweden': '\\d{3}\\s?\\d{2}', - 'United Kingdom': '[A-Za-z]{1,2}[0-9Rr][0-9A-Za-z]? [0-9][ABD-HJLNP-UW-Zabd-hjlnp-uw-z]{2}' -}; -/* eslint-enable */ - diff --git a/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts b/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts index 8d04eb34c7..29ed565b6f 100644 --- a/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts +++ b/ui-ngx/src/app/modules/home/pages/customer/customer.component.ts @@ -26,6 +26,7 @@ import { EntityTableConfig } from '@home/models/entity/entities-table-config.mod import { isDefinedAndNotNull } from '@core/utils'; import { getCurrentAuthState } from '@core/auth/auth.selectors'; import { AuthState } from '@core/auth/auth.models'; +import { CountryData } from '@shared/models/country.models'; @Component({ selector: 'tb-customer', @@ -43,8 +44,9 @@ export class CustomerComponent extends ContactBasedComponent { @Inject('entity') protected entityValue: Customer, @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig, protected fb: UntypedFormBuilder, - protected cd: ChangeDetectorRef) { - super(store, fb, entityValue, entitiesTableConfigValue, cd); + protected cd: ChangeDetectorRef, + protected countryData: CountryData) { + super(store, fb, entityValue, entitiesTableConfigValue, cd, countryData); } hideDelete() { diff --git a/ui-ngx/src/app/modules/home/pages/tenant/tenant.component.ts b/ui-ngx/src/app/modules/home/pages/tenant/tenant.component.ts index e35d990ecb..9858850437 100644 --- a/ui-ngx/src/app/modules/home/pages/tenant/tenant.component.ts +++ b/ui-ngx/src/app/modules/home/pages/tenant/tenant.component.ts @@ -24,6 +24,7 @@ import { TranslateService } from '@ngx-translate/core'; import { ContactBasedComponent } from '../../components/entity/contact-based.component'; import { EntityTableConfig } from '@home/models/entity/entities-table-config.models'; import { isDefinedAndNotNull } from '@core/utils'; +import { CountryData } from '@shared/models/country.models'; @Component({ selector: 'tb-tenant', @@ -37,8 +38,9 @@ export class TenantComponent extends ContactBasedComponent { @Inject('entity') protected entityValue: TenantInfo, @Inject('entitiesTableConfig') protected entitiesTableConfigValue: EntityTableConfig, protected fb: UntypedFormBuilder, - protected cd: ChangeDetectorRef) { - super(store, fb, entityValue, entitiesTableConfigValue, cd); + protected cd: ChangeDetectorRef, + protected countryData: CountryData) { + super(store, fb, entityValue, entitiesTableConfigValue, cd, countryData); } hideDelete() { diff --git a/ui-ngx/src/app/shared/components/contact.component.html b/ui-ngx/src/app/shared/components/contact.component.html index 059fd09c80..0f4038abe9 100644 --- a/ui-ngx/src/app/shared/components/contact.component.html +++ b/ui-ngx/src/app/shared/components/contact.component.html @@ -16,14 +16,10 @@ -->
- - contact.country - - - {{ country }} - - - + +
contact.city @@ -56,6 +52,7 @@ diff --git a/ui-ngx/src/app/shared/components/contact.component.ts b/ui-ngx/src/app/shared/components/contact.component.ts index c5a3daecf8..a344f8a715 100644 --- a/ui-ngx/src/app/shared/components/contact.component.ts +++ b/ui-ngx/src/app/shared/components/contact.component.ts @@ -16,7 +16,6 @@ import { Component, Input } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; -import { COUNTRIES } from '@home/models/contact.models'; @Component({ selector: 'tb-contact', @@ -29,6 +28,15 @@ export class ContactComponent { @Input() isEdit: boolean; - countries = COUNTRIES; + phoneInputDefaultCountry = 'US'; + constructor() { + } + + changeCountry(countryCode: string) { + this.phoneInputDefaultCountry = countryCode ?? 'US'; + setTimeout(() => { + this.parentForm.get('phone').setValue(this.parentForm.get('phone').value); + }); + } } diff --git a/ui-ngx/src/app/shared/components/country-autocomplete.component.html b/ui-ngx/src/app/shared/components/country-autocomplete.component.html new file mode 100644 index 0000000000..eadf630dcd --- /dev/null +++ b/ui-ngx/src/app/shared/components/country-autocomplete.component.html @@ -0,0 +1,58 @@ + + + {{ labelText }} + + + + + {{country.flag}} + + + +
+
+ contact.no-country-found +
+ + + {{ 'contact.no-country-matching' | translate: + {country: (searchText | truncate: true: 6: '...')} }} + + +
+
+
+ {{ autocompleteHint }} + + {{ requiredText }} + +
diff --git a/ui-ngx/src/app/shared/components/country-autocomplete.component.ts b/ui-ngx/src/app/shared/components/country-autocomplete.component.ts new file mode 100644 index 0000000000..7fc3a10bca --- /dev/null +++ b/ui-ngx/src/app/shared/components/country-autocomplete.component.ts @@ -0,0 +1,209 @@ +/// +/// 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 { Component, ElementRef, EventEmitter, forwardRef, Input, OnInit, Output, ViewChild } from '@angular/core'; +import { Country, CountryData } from '@shared/models/country.models'; +import { + ControlValueAccessor, + FormBuilder, + FormGroup, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + ValidationErrors, + Validator +} from '@angular/forms'; +import { isNotEmptyStr } from '@core/utils'; +import { Observable, of } from 'rxjs'; +import { debounceTime, distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators'; +import { SubscriptSizing } from '@angular/material/form-field'; +import { coerceBoolean } from '@shared/decorators/coercion'; +import { TranslateService } from '@ngx-translate/core'; + +interface CountrySearchData extends Country { + searchText?: string; +} + +@Component({ + selector: 'tb-country-autocomplete', + templateUrl: 'country-autocomplete.component.html', + providers: [ + CountryData, + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => CountryAutocompleteComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => CountryAutocompleteComponent), + multi: true + } + ] +}) +export class CountryAutocompleteComponent implements OnInit, ControlValueAccessor, Validator { + + @Input() + labelText = this.translate.instant('contact.country'); + + @Input() + requiredText = this.translate.instant('contact.country-required'); + + @Input() + autocompleteHint: string; + + @Input() + disabled: boolean; + + @Input() + @coerceBoolean() + required = false; + + @Input() + subscriptSizing: SubscriptSizing = 'fixed'; + + @ViewChild('countryInput', {static: true}) countryInput: ElementRef; + + @Output() + selectCountryCode = new EventEmitter(); + + countryFormGroup: FormGroup; + + searchText = ''; + + filteredCountries: Observable>; + + onTouched = () => { + }; + private propagateChange: (value: any) => void = () => { + }; + + private modelValue: Country; + + private allCountries: CountrySearchData[] = this.countryData.allCountries; + private initSearchData = false; + private dirty = false; + + constructor(private fb: FormBuilder, + private countryData: CountryData, + private translate: TranslateService) { + this.countryFormGroup = this.fb.group({ + country: [''] + }); + } + + ngOnInit(): void { + this.filteredCountries = this.countryFormGroup.get('country').valueChanges.pipe( + debounceTime(150), + tap(value => { + let modelValue: Country; + if (typeof value === 'string' || !value) { + modelValue = null; + } else { + modelValue = value; + } + this.updateView(modelValue); + if (value === null) { + this.clear(); + } + }), + map(value => value ? (typeof value === 'string' ? value : value.name) : ''), + distinctUntilChanged(), + switchMap(name => of(this.fetchCountries(name))), + share() + ); + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + this.onTouched = fn; + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (isDisabled) { + this.countryFormGroup.disable({emitEvent: false}); + } else { + this.countryFormGroup.enable({emitEvent: false}); + } + } + + validate(): ValidationErrors | null { + return this.countryFormGroup.valid ? null : { + countryFormGroup: false + }; + } + + writeValue(country: string) { + this.dirty = true; + + const findCountry = isNotEmptyStr(country) ? this.allCountries.find(item => item.name === country) : null; + + this.modelValue = findCountry || null; + this.countryFormGroup.get('country').patchValue(this.modelValue || '', { emitEvent: false }); + this.selectCountryCode.emit(this.modelValue ? this.modelValue.iso2 : null); + } + + displayCountryFn(country?: Country): string | undefined { + return country ? `${country.flag} ${country.name}` : undefined; + } + + onFocus() { + if (this.dirty) { + this.countryFormGroup.get('country').updateValueAndValidity({onlySelf: true}); + this.dirty = false; + } + } + + textIsNotEmpty(text: string): boolean { + return (text && text.length > 0); + } + + clear() { + this.countryFormGroup.get('country').patchValue('', {emitEvent: true}); + setTimeout(() => { + this.countryInput.nativeElement.blur(); + this.countryInput.nativeElement.focus(); + }, 0); + } + + private fetchCountries(searchText: string): Country[] { + this.searchText = searchText; + if (!this.initSearchData) { + this.allCountries.forEach(country => { + country.searchText = `${country.name} ${country.iso2}`.toLowerCase(); + }); + this.initSearchData = true; + } + if (isNotEmptyStr(searchText)) { + const filterValue = searchText.toLowerCase(); + return this.allCountries.filter(country => country.searchText.includes(filterValue)); + } + return this.allCountries; + } + + private updateView(value: Country | null) { + if (this.modelValue?.name !== value?.name) { + this.modelValue = value; + this.propagateChange(this.modelValue); + if (value) { + this.selectCountryCode.emit(value.iso2); + } + } + } +} diff --git a/ui-ngx/src/app/shared/models/country.models.ts b/ui-ngx/src/app/shared/models/country.models.ts index 814cb81147..d8563e2449 100644 --- a/ui-ngx/src/app/shared/models/country.models.ts +++ b/ui-ngx/src/app/shared/models/country.models.ts @@ -22,6 +22,7 @@ export interface Country { dialCode: string; areaCodes?: string[]; flag: string; + postCodePattern?: RegExp; } export enum CountryISO { @@ -32,6 +33,7 @@ export enum CountryISO { Andorra = 'AD', Angola = 'AO', Anguilla = 'AI', + Antarctica = 'AQ', AntiguaAndBarbuda = 'AG', Argentina = 'AR', Armenia = 'AM', @@ -50,6 +52,8 @@ export enum CountryISO { Bermuda = 'BM', Bhutan = 'BT', Bolivia = 'BO', + BonaireAndSintEustatiusAndSaba = 'BQ', + BouvetIsland = 'BV', BosniaAndHerzegovina = 'BA', Botswana = 'BW', Brazil = 'BR', @@ -77,10 +81,10 @@ export enum CountryISO { CongoRepublicCongoBrazzaville = 'CG', CookIslands = 'CK', CostaRica = 'CR', - CôteDIvoire = 'CI', + CoteDivoire = 'CI', Croatia = 'HR', Cuba = 'CU', - Curaçao = 'CW', + Curacao = 'CW', Cyprus = 'CY', CzechRepublic = 'CZ', Denmark = 'DK', @@ -101,6 +105,7 @@ export enum CountryISO { France = 'FR', FrenchGuiana = 'GF', FrenchPolynesia = 'PF', + FrenchSouthernTerritories = 'TF', Gabon = 'GA', Gambia = 'GM', Georgia = 'GE', @@ -118,6 +123,7 @@ export enum CountryISO { GuineaBissau = 'GW', Guyana = 'GY', Haiti = 'HT', + HeardIslandandMcDonaldIslands = 'HM', Honduras = 'HN', HongKong = 'HK', Hungary = 'HU', @@ -150,7 +156,6 @@ export enum CountryISO { Lithuania = 'LT', Luxembourg = 'LU', Macau = 'MO', - Macedonia = 'MK', Madagascar = 'MG', Malawi = 'MW', Malaysia = 'MY', @@ -184,6 +189,7 @@ export enum CountryISO { Niue = 'NU', NorfolkIsland = 'NF', NorthKorea = 'KP', + NorthMacedonia = 'MK', NorthernMarianaIslands = 'MP', Norway = 'NO', Oman = 'OM', @@ -195,15 +201,16 @@ export enum CountryISO { Paraguay = 'PY', Peru = 'PE', Philippines = 'PH', + PitcairnIslands = 'PN', Poland = 'PL', Portugal = 'PT', PuertoRico = 'PR', Qatar = 'QA', - Réunion = 'RE', + Reunion = 'RE', Romania = 'RO', Russia = 'RU', Rwanda = 'RW', - SaintBarthélemy = 'BL', + SaintBarthelemy = 'BL', SaintHelena = 'SH', SaintKittsAndNevis = 'KN', SaintLucia = 'LC', @@ -212,7 +219,7 @@ export enum CountryISO { SaintVincentAndTheGrenadines = 'VC', Samoa = 'WS', SanMarino = 'SM', - SãoToméAndPríncipe = 'ST', + SaoTomeAndPrincipe = 'ST', SaudiArabia = 'SA', Senegal = 'SN', Serbia = 'RS', @@ -225,6 +232,7 @@ export enum CountryISO { SolomonIslands = 'SB', Somalia = 'SO', SouthAfrica = 'ZA', + SouthGeorgiaAndTheSouthSandwichIslands = 'GS', SouthKorea = 'KR', SouthSudan = 'SS', Spain = 'ES', @@ -267,9 +275,10 @@ export enum CountryISO { Yemen = 'YE', Zambia = 'ZM', Zimbabwe = 'ZW', - ÅlandIslands = 'AX', + AlandIslands = 'AX', } +/* eslint-disable max-len */ @Injectable() export class CountryData { public allCountries: Array = [ @@ -280,36 +289,39 @@ export class CountryData { {name: 'Andorra', iso2: CountryISO.Andorra, dialCode: '376', flag: '🇦🇩'}, {name: 'Angola', iso2: CountryISO.Angola, dialCode: '244', flag: '🇦🇴'}, {name: 'Anguilla', iso2: CountryISO.Anguilla, dialCode: '1', flag: '🇦🇮'}, + {name: 'Antarctica', iso2: CountryISO.Antarctica, dialCode: '672', flag: '🇦🇶'}, {name: 'Antigua and Barbuda', iso2: CountryISO.AntiguaAndBarbuda, dialCode: '1', flag: '🇦🇬'}, {name: 'Argentina', iso2: CountryISO.Argentina, dialCode: '54', flag: '🇦🇷'}, {name: 'Armenia', iso2: CountryISO.Armenia, dialCode: '374', flag: '🇦🇲'}, {name: 'Aruba', iso2: CountryISO.Aruba, dialCode: '297', flag: '🇦🇼'}, - {name: 'Australia', iso2: CountryISO.Australia, dialCode: '61', flag: '🇦🇺'}, - {name: 'Austria', iso2: CountryISO.Austria, dialCode: '43', flag: '🇦🇹'}, + {name: 'Australia', iso2: CountryISO.Australia, dialCode: '61', flag: '🇦🇺', postCodePattern: /[0-9]{4}/}, + {name: 'Austria', iso2: CountryISO.Austria, dialCode: '43', flag: '🇦🇹', postCodePattern: /[0-9]{4}/}, {name: 'Azerbaijan', iso2: CountryISO.Azerbaijan, dialCode: '994', flag: '🇦🇿'}, {name: 'Bahamas', iso2: CountryISO.Bahamas, dialCode: '1', flag: '🇧🇸'}, {name: 'Bahrain', iso2: CountryISO.Bahrain, dialCode: '973', flag: '🇧🇭'}, {name: 'Bangladesh', iso2: CountryISO.Bangladesh, dialCode: '880', flag: '🇧🇩'}, {name: 'Barbados', iso2: CountryISO.Barbados, dialCode: '1', flag: '🇧🇧'}, {name: 'Belarus', iso2: CountryISO.Belarus, dialCode: '375', flag: '🇧🇾'}, - {name: 'Belgium', iso2: CountryISO.Belgium, dialCode: '32', flag: '🇧🇪'}, + {name: 'Belgium', iso2: CountryISO.Belgium, dialCode: '32', flag: '🇧🇪', postCodePattern: /[0-9]{4}/}, {name: 'Belize', iso2: CountryISO.Belize, dialCode: '501', flag: '🇧🇿'}, {name: 'Benin', iso2: CountryISO.Benin, dialCode: '229', flag: '🇧🇯'}, {name: 'Bermuda', iso2: CountryISO.Bermuda, dialCode: '1', flag: '🇧🇲'}, {name: 'Bhutan', iso2: CountryISO.Bhutan, dialCode: '975', flag: '🇧🇹'}, {name: 'Bolivia', iso2: CountryISO.Bolivia, dialCode: '591', flag: '🇧🇴'}, + {name: 'Bonaire, Sint Eustatius and Saba', iso2: CountryISO.BonaireAndSintEustatiusAndSaba, dialCode: '599', flag: '🇧🇶'}, + {name: 'Bouvet Island', iso2: CountryISO.BouvetIsland, dialCode: '47', flag: '🇧🇻'}, {name: 'Bosnia and Herzegovina', iso2: CountryISO.BosniaAndHerzegovina, dialCode: '387', flag: '🇧🇦'}, {name: 'Botswana', iso2: CountryISO.Botswana, dialCode: '267', flag: '🇧🇼'}, - {name: 'Brazil', iso2: CountryISO.Brazil, dialCode: '55', flag: '🇧🇷'}, + {name: 'Brazil', iso2: CountryISO.Brazil, dialCode: '55', flag: '🇧🇷', postCodePattern: /[0-9]{5}-?[0-9]{3}/}, {name: 'British Indian Ocean Territory', iso2: CountryISO.BritishIndianOceanTerritory, dialCode: '246', flag: '🇮🇴'}, {name: 'British Virgin Islands', iso2: CountryISO.BritishVirginIslands, dialCode: '1', flag: '🇻🇬'}, - {name: 'Brunei', iso2: CountryISO.Brunei, dialCode: '673', flag: '🇧🇳'}, + {name: 'Brunei Darussalam', iso2: CountryISO.Brunei, dialCode: '673', flag: '🇧🇳'}, {name: 'Bulgaria', iso2: CountryISO.Bulgaria, dialCode: '359', flag: '🇧🇬'}, {name: 'Burkina Faso', iso2: CountryISO.BurkinaFaso, dialCode: '226', flag: '🇧🇫'}, {name: 'Burundi', iso2: CountryISO.Burundi, dialCode: '257', flag: '🇧🇮'}, {name: 'Cambodia', iso2: CountryISO.Cambodia, dialCode: '855', flag: '🇰🇭'}, {name: 'Cameroon', iso2: CountryISO.Cameroon, dialCode: '237', flag: '🇨🇲'}, - {name: 'Canada', iso2: CountryISO.Canada, dialCode: '1', flag: '🇨🇦'}, + {name: 'Canada', iso2: CountryISO.Canada, dialCode: '1', flag: '🇨🇦', postCodePattern: /^(?!.*[DFIOQU])[A-VXY][0-9][A-Z][ -]?[0-9][A-Z][0-9]$/}, {name: 'Cape Verde', iso2: CountryISO.CapeVerde, dialCode: '238', flag: '🇨🇻'}, {name: 'Caribbean Netherlands', iso2: CountryISO.CaribbeanNetherlands, dialCode: '599', flag: '🇧🇶'}, {name: 'Cayman Islands', iso2: CountryISO.CaymanIslands, dialCode: '1', flag: '🇰🇾'}, @@ -318,20 +330,20 @@ export class CountryData { {name: 'Chile', iso2: CountryISO.Chile, dialCode: '56', flag: '🇨🇱'}, {name: 'China', iso2: CountryISO.China, dialCode: '86', flag: '🇨🇳'}, {name: 'Christmas Island', iso2: CountryISO.ChristmasIsland, dialCode: '61', flag: '🇨🇽'}, - {name: 'Cocos Islands', iso2: CountryISO.Cocos, dialCode: '61', flag: '🇨🇨'}, + {name: 'Cocos (Keeling) Islands', iso2: CountryISO.Cocos, dialCode: '61', flag: '🇨🇨'}, {name: 'Colombia', iso2: CountryISO.Colombia, dialCode: '57', flag: '🇨🇨'}, {name: 'Comoros', iso2: CountryISO.Comoros, dialCode: '269', flag: '🇰🇲'}, - {name: 'Congo-Kinshasa', iso2: CountryISO.CongoDRCJamhuriYaKidemokrasiaYaKongo, dialCode: '243', flag: '🇨🇩'}, - {name: 'Congo-Brazzaville', iso2: CountryISO.CongoRepublicCongoBrazzaville, dialCode: '242', flag: '🇨🇬'}, + {name: 'Congo', iso2: CountryISO.CongoDRCJamhuriYaKidemokrasiaYaKongo, dialCode: '243', flag: '🇨🇩'}, + {name: 'Congo, Democratic Republic of the', iso2: CountryISO.CongoRepublicCongoBrazzaville, dialCode: '242', flag: '🇨🇬'}, {name: 'Cook Islands', iso2: CountryISO.CookIslands, dialCode: '682', flag: '🇨🇰'}, {name: 'Costa Rica', iso2: CountryISO.CostaRica, dialCode: '506', flag: '🇨🇷'}, - {name: 'Côte d’Ivoire', iso2: CountryISO.CôteDIvoire, dialCode: '225', flag: '🇨🇮'}, + {name: 'Côte d\'Ivoire', iso2: CountryISO.CoteDivoire, dialCode: '225', flag: '🇨🇮'}, {name: 'Croatia', iso2: CountryISO.Croatia, dialCode: '385', flag: '🇭🇷'}, {name: 'Cuba', iso2: CountryISO.Cuba, dialCode: '53', flag: '🇨🇺'}, - {name: 'Curaçao', iso2: CountryISO.Curaçao, dialCode: '599', flag: '🇨🇼'}, + {name: 'Curaçao', iso2: CountryISO.Curacao, dialCode: '599', flag: '🇨🇼'}, {name: 'Cyprus', iso2: CountryISO.Cyprus, dialCode: '357', flag: '🇨🇾'}, {name: 'Czech Republic', iso2: CountryISO.CzechRepublic, dialCode: '420', flag: '🇨🇿'}, - {name: 'Denmark', iso2: CountryISO.Denmark, dialCode: '45', flag: '🇩🇰'}, + {name: 'Denmark', iso2: CountryISO.Denmark, dialCode: '45', flag: '🇩🇰', postCodePattern: /[0-9]{3,4}/}, {name: 'Djibouti', iso2: CountryISO.Djibouti, dialCode: '253', flag: '🇩🇯'}, {name: 'Dominica', iso2: CountryISO.Dominica, dialCode: '1767', flag: '🇩🇲'}, {name: 'Dominican Republic', iso2: CountryISO.DominicanRepublic, dialCode: '1', flag: '🇩🇴'}, @@ -342,17 +354,18 @@ export class CountryData { {name: 'Eritrea', iso2: CountryISO.Eritrea, dialCode: '291', flag: '🇪🇷'}, {name: 'Estonia', iso2: CountryISO.Estonia, dialCode: '372', flag: '🇪🇪'}, {name: 'Ethiopia', iso2: CountryISO.Ethiopia, dialCode: '251', flag: '🇪🇹'}, - {name: 'Falkland Islands', iso2: CountryISO.FalklandIslands, dialCode: '500', flag: '🇫🇰'}, - {name: 'Faroe Islands', iso2: CountryISO.FaroeIslands, dialCode: '298', flag: '🇫🇴'}, + {name: 'Falkland Islands (Malvinas)', iso2: CountryISO.FalklandIslands, dialCode: '500', flag: '🇫🇰'}, + {name: 'Faroe Islands', iso2: CountryISO.FaroeIslands, dialCode: '298', flag: '🇫🇴', postCodePattern: /[0-9]{3,4}/}, {name: 'Fiji', iso2: CountryISO.Fiji, dialCode: '679', flag: '🇫🇯'}, {name: 'Finland', iso2: CountryISO.Finland, dialCode: '358', flag: '🇫🇮'}, {name: 'France', iso2: CountryISO.France, dialCode: '33', flag: '🇫🇷'}, {name: 'French Guiana', iso2: CountryISO.FrenchGuiana, dialCode: '594', flag: '🇬🇫'}, {name: 'French Polynesia', iso2: CountryISO.FrenchPolynesia, dialCode: '689', flag: '🇵🇫'}, + {name: 'French Southern Territories', iso2: CountryISO.FrenchSouthernTerritories, dialCode: '262', flag: '🇹🇫'}, {name: 'Gabon', iso2: CountryISO.Gabon, dialCode: '241', flag: '🇬🇦'}, {name: 'Gambia', iso2: CountryISO.Gambia, dialCode: '220', flag: '🇬🇲'}, {name: 'Georgia', iso2: CountryISO.Georgia, dialCode: '995', flag: '🇬🇪'}, - {name: 'Germany', iso2: CountryISO.Germany, dialCode: '49', flag: '🇩🇪'}, + {name: 'Germany', iso2: CountryISO.Germany, dialCode: '49', flag: '🇩🇪', postCodePattern: /[0-9]{5}/}, {name: 'Ghana', iso2: CountryISO.Ghana, dialCode: '233', flag: '🇬🇭'}, {name: 'Gibraltar', iso2: CountryISO.Gibraltar, dialCode: '350', flag: '🇬🇮'}, {name: 'Greece', iso2: CountryISO.Greece, dialCode: '30', flag: '🇬🇷'}, @@ -366,20 +379,21 @@ export class CountryData { {name: 'Guinea-Bissau', iso2: CountryISO.GuineaBissau, dialCode: '245', flag: '🇬🇼'}, {name: 'Guyana', iso2: CountryISO.Guyana, dialCode: '592', flag: '🇬🇾'}, {name: 'Haiti', iso2: CountryISO.Haiti, dialCode: '509', flag: '🇭🇹'}, + {name: 'Heard Island and McDonald Islands', iso2: CountryISO.HeardIslandandMcDonaldIslands, dialCode: '672', flag: '🇭🇲'}, {name: 'Honduras', iso2: CountryISO.Honduras, dialCode: '504', flag: '🇭🇳'}, {name: 'Hong Kong', iso2: CountryISO.HongKong, dialCode: '852', flag: '🇭🇰'}, - {name: 'Hungary', iso2: CountryISO.Hungary, dialCode: '36', flag: '🇭🇺'}, + {name: 'Hungary', iso2: CountryISO.Hungary, dialCode: '36', flag: '🇭🇺', postCodePattern: /[0-9]{4}/}, {name: 'Iceland', iso2: CountryISO.Iceland, dialCode: '354', flag: '🇮🇸'}, {name: 'India', iso2: CountryISO.India, dialCode: '91', flag: '🇮🇳'}, {name: 'Indonesia', iso2: CountryISO.Indonesia, dialCode: '62', flag: '🇮🇩'}, - {name: 'Iran', iso2: CountryISO.Iran, dialCode: '98', flag: '🇮🇷'}, + {name: 'Islamic Republic of Iran', iso2: CountryISO.Iran, dialCode: '98', flag: '🇮🇷'}, {name: 'Iraq', iso2: CountryISO.Iraq, dialCode: '964', flag: '🇮🇶'}, {name: 'Ireland', iso2: CountryISO.Ireland, dialCode: '353', flag: '🇮🇪'}, {name: 'Isle of Man', iso2: CountryISO.IsleOfMan, dialCode: '44', flag: '🇮🇲'}, {name: 'Israel', iso2: CountryISO.Israel, dialCode: '972', flag: '🇮🇱'}, - {name: 'Italy', iso2: CountryISO.Italy, dialCode: '39', flag: '🇮🇹'}, + {name: 'Italy', iso2: CountryISO.Italy, dialCode: '39', flag: '🇮🇹', postCodePattern: /[0-9]{5}/}, {name: 'Jamaica', iso2: CountryISO.Jamaica, dialCode: '1', flag: '🇯🇲'}, - {name: 'Japan', iso2: CountryISO.Japan, dialCode: '81', flag: '🇯🇵'}, + {name: 'Japan', iso2: CountryISO.Japan, dialCode: '81', flag: '🇯🇵', postCodePattern: /\d{3}-\d{4}/}, {name: 'Jersey', iso2: CountryISO.Jersey, dialCode: '44', flag: '🇯🇪'}, {name: 'Jordan', iso2: CountryISO.Jordan, dialCode: '962', flag: '🇯🇴'}, {name: 'Kazakhstan', iso2: CountryISO.Kazakhstan, dialCode: '7', flag: '🇰🇿'}, @@ -388,7 +402,7 @@ export class CountryData { {name: 'Kosovo', iso2: CountryISO.Kosovo, dialCode: '383', flag: '🇽🇰'}, {name: 'Kuwait', iso2: CountryISO.Kuwait, dialCode: '965', flag: '🇰🇼'}, {name: 'Kyrgyzstan', iso2: CountryISO.Kyrgyzstan, dialCode: '996', flag: '🇰🇬'}, - {name: 'Laos', iso2: CountryISO.Laos, dialCode: '856', flag: '🇱🇦'}, + {name: 'Lao People\'s Democratic Republic', iso2: CountryISO.Laos, dialCode: '856', flag: '🇱🇦'}, {name: 'Latvia', iso2: CountryISO.Latvia, dialCode: '371', flag: '🇱🇻'}, {name: 'Lebanon', iso2: CountryISO.Lebanon, dialCode: '961', flag: '🇱🇧'}, {name: 'Lesotho', iso2: CountryISO.Lesotho, dialCode: '266', flag: '🇱🇸'}, @@ -396,9 +410,8 @@ export class CountryData { {name: 'Libya', iso2: CountryISO.Libya, dialCode: '218', flag: '🇱🇾'}, {name: 'Liechtenstein', iso2: CountryISO.Liechtenstein, dialCode: '423', flag: '🇱🇮'}, {name: 'Lithuania', iso2: CountryISO.Lithuania, dialCode: '370', flag: '🇱🇹'}, - {name: 'Luxembourg', iso2: CountryISO.Luxembourg, dialCode: '352', flag: '🇱🇺'}, - {name: 'Macau', iso2: CountryISO.Macau, dialCode: '853', flag: '🇲🇴'}, - {name: 'Macedonia', iso2: CountryISO.Macedonia, dialCode: '389', flag: '🇲🇰'}, + {name: 'Luxembourg', iso2: CountryISO.Luxembourg, dialCode: '352', flag: '🇱🇺', postCodePattern: /(L\s*([-—–]))\s*?\d{4}/}, + {name: 'Macao', iso2: CountryISO.Macau, dialCode: '853', flag: '🇲🇴'}, {name: 'Madagascar', iso2: CountryISO.Madagascar, dialCode: '261', flag: '🇲🇬'}, {name: 'Malawi', iso2: CountryISO.Malawi, dialCode: '265', flag: '🇲🇼'}, {name: 'Malaysia', iso2: CountryISO.Malaysia, dialCode: '60', flag: '🇲🇾'}, @@ -411,8 +424,8 @@ export class CountryData { {name: 'Mauritius', iso2: CountryISO.Mauritius, dialCode: '230', flag: '🇲🇺'}, {name: 'Mayotte', iso2: CountryISO.Mayotte, dialCode: '262', flag: '🇾🇹'}, {name: 'Mexico', iso2: CountryISO.Mexico, dialCode: '52', flag: '🇲🇽'}, - {name: 'Micronesia', iso2: CountryISO.Micronesia, dialCode: '691', flag: '🇫🇲'}, - {name: 'Moldova', iso2: CountryISO.Moldova, dialCode: '373', flag: '🇲🇩'}, + {name: 'Micronesia, Federated States of', iso2: CountryISO.Micronesia, dialCode: '691', flag: '🇫🇲'}, + {name: 'Moldova, Republic of', iso2: CountryISO.Moldova, dialCode: '373', flag: '🇲🇩'}, {name: 'Monaco', iso2: CountryISO.Monaco, dialCode: '377', flag: '🇲🇨'}, {name: 'Mongolia', iso2: CountryISO.Mongolia, dialCode: '976', flag: '🇲🇳'}, {name: 'Montenegro', iso2: CountryISO.Montenegro, dialCode: '382', flag: '🇲🇪'}, @@ -423,7 +436,7 @@ export class CountryData { {name: 'Namibia', iso2: CountryISO.Namibia, dialCode: '264', flag: '🇳🇦'}, {name: 'Nauru', iso2: CountryISO.Nauru, dialCode: '674', flag: '🇳🇷'}, {name: 'Nepal', iso2: CountryISO.Nepal, dialCode: '977', flag: '🇳🇵'}, - {name: 'Netherlands', iso2: CountryISO.Netherlands, dialCode: '31', flag: '🇳🇱'}, + {name: 'Netherlands', iso2: CountryISO.Netherlands, dialCode: '31', flag: '🇳🇱', postCodePattern: /[1-9][0-9]{3}\s?[a-zA-Z]{2}/}, {name: 'New Caledonia', iso2: CountryISO.NewCaledonia, dialCode: '687', flag: '🇳🇨'}, {name: 'New Zealand', iso2: CountryISO.NewZealand, dialCode: '64', flag: '🇳🇿'}, {name: 'Nicaragua', iso2: CountryISO.Nicaragua, dialCode: '505', flag: '🇳🇮'}, @@ -432,61 +445,65 @@ export class CountryData { {name: 'Niue', iso2: CountryISO.Niue, dialCode: '683', flag: '🇳🇺'}, {name: 'Norfolk Island', iso2: CountryISO.NorfolkIsland, dialCode: '672', flag: '🇳🇫'}, {name: 'North Korea', iso2: CountryISO.NorthKorea, dialCode: '850', flag: '🇰🇵'}, + {name: 'North Macedonia', iso2: CountryISO.NorthMacedonia, dialCode: '389', flag: '🇲🇰'}, {name: 'Northern Mariana Islands', iso2: CountryISO.NorthernMarianaIslands, dialCode: '1', flag: '🇲🇵'}, {name: 'Norway', iso2: CountryISO.Norway, dialCode: '47', flag: '🇳🇴'}, {name: 'Oman', iso2: CountryISO.Oman, dialCode: '968', flag: '🇴🇲'}, {name: 'Pakistan', iso2: CountryISO.Pakistan, dialCode: '92', flag: '🇵🇰'}, {name: 'Palau', iso2: CountryISO.Palau, dialCode: '680', flag: '🇵🇼'}, - {name: 'Palestine', iso2: CountryISO.Palestine, dialCode: '970', flag: '🇵🇸'}, + {name: 'Palestine, State of', iso2: CountryISO.Palestine, dialCode: '970', flag: '🇵🇸'}, {name: 'Panama', iso2: CountryISO.Panama, dialCode: '507', flag: '🇵🇦'}, {name: 'Papua New Guinea', iso2: CountryISO.PapuaNewGuinea, dialCode: '675', flag: '🇵🇬'}, {name: 'Paraguay', iso2: CountryISO.Paraguay, dialCode: '595', flag: '🇵🇾'}, {name: 'Peru', iso2: CountryISO.Peru, dialCode: '51', flag: '🇵🇪'}, {name: 'Philippines', iso2: CountryISO.Philippines, dialCode: '63', flag: '🇵🇭'}, - {name: 'Poland', iso2: CountryISO.Poland, dialCode: '48', flag: '🇵🇱'}, + {name: 'Pitcairn Islands', iso2: CountryISO.PitcairnIslands, dialCode: '649', flag: '🇵🇳'}, + {name: 'Poland', iso2: CountryISO.Poland, dialCode: '48', flag: '🇵🇱', postCodePattern: /[0-9]{2}-[0-9]{3}/}, {name: 'Portugal', iso2: CountryISO.Portugal, dialCode: '351', flag: '🇵🇹'}, {name: 'Puerto Rico', iso2: CountryISO.PuertoRico, dialCode: '1', flag: '🇵🇷'}, {name: 'Qatar', iso2: CountryISO.Qatar, dialCode: '974', flag: '🇶🇦'}, - {name: 'Réunion', iso2: CountryISO.Réunion, dialCode: '262', flag: '🇷🇪'}, + {name: 'Réunion', iso2: CountryISO.Reunion, dialCode: '262', flag: '🇷🇪'}, {name: 'Romania', iso2: CountryISO.Romania, dialCode: '40', flag: '🇷🇴'}, - {name: 'Russia', iso2: CountryISO.Russia, dialCode: '7', flag: '🇷🇺'}, + {name: 'Russian Federation', iso2: CountryISO.Russia, dialCode: '7', flag: '🇷🇺'}, {name: 'Rwanda', iso2: CountryISO.Rwanda, dialCode: '250', flag: '🇷🇼'}, - {name: 'Saint Barthélemy', iso2: CountryISO.SaintBarthélemy, dialCode: '590', flag: '🇧🇱'}, - {name: 'Saint Helena', iso2: CountryISO.SaintHelena, dialCode: '290', flag: '🇸🇭'}, + {name: 'Saint Barthélemy', iso2: CountryISO.SaintBarthelemy, dialCode: '590', flag: '🇧🇱'}, + {name: 'Saint Helena, Ascension and Tristan da Cunha', iso2: CountryISO.SaintHelena, dialCode: '290', flag: '🇸🇭'}, {name: 'Saint Kitts and Nevis', iso2: CountryISO.SaintKittsAndNevis, dialCode: '1', flag: '🇰🇳'}, {name: 'Saint Lucia', iso2: CountryISO.SaintLucia, dialCode: '1', flag: '🇱🇨'}, - {name: 'Saint Martin', iso2: CountryISO.SaintMartin, dialCode: '590', flag: '🇲🇫'}, + {name: 'Saint Martin (French part)', iso2: CountryISO.SaintMartin, dialCode: '590', flag: '🇲🇫'}, {name: 'Saint Pierre and Miquelon', iso2: CountryISO.SaintPierreAndMiquelon, dialCode: '508', flag: '🇵🇲'}, {name: 'Saint Vincent and the Grenadines', iso2: CountryISO.SaintVincentAndTheGrenadines, dialCode: '1', flag: '🇻🇨'}, {name: 'Samoa', iso2: CountryISO.Samoa, dialCode: '685', flag: '🇼🇸'}, {name: 'San Marino', iso2: CountryISO.SanMarino, dialCode: '378', flag: '🇸🇲'}, - {name: 'São Tomé and Príncipe', iso2: CountryISO.SãoToméAndPríncipe, dialCode: '239', flag: '🇸🇹'}, + {name: 'Sao Tome and Principe', iso2: CountryISO.SaoTomeAndPrincipe, dialCode: '239', flag: '🇸🇹'}, {name: 'Saudi Arabia', iso2: CountryISO.SaudiArabia, dialCode: '966', flag: '🇸🇦'}, {name: 'Senegal', iso2: CountryISO.Senegal, dialCode: '221', flag: '🇸🇳'}, {name: 'Serbia', iso2: CountryISO.Serbia, dialCode: '381', flag: '🇷🇸'}, {name: 'Seychelles', iso2: CountryISO.Seychelles, dialCode: '248', flag: '🇸🇨'}, {name: 'Sierra Leone', iso2: CountryISO.SierraLeone, dialCode: '232', flag: '🇸🇱'}, {name: 'Singapore', iso2: CountryISO.Singapore, dialCode: '65', flag: '🇸🇬'}, - {name: 'Sint Maarten', iso2: CountryISO.SintMaarten, dialCode: '1', flag: '🇸🇽'}, + {name: 'Sint Maarten (Dutch Part)', iso2: CountryISO.SintMaarten, dialCode: '1', flag: '🇸🇽'}, {name: 'Slovakia', iso2: CountryISO.Slovakia, dialCode: '421', flag: '🇸🇰'}, {name: 'Slovenia', iso2: CountryISO.Slovenia, dialCode: '386', flag: '🇸🇮'}, {name: 'Solomon Islands', iso2: CountryISO.SolomonIslands, dialCode: '677', flag: '🇸🇧'}, {name: 'Somalia', iso2: CountryISO.Somalia, dialCode: '252', flag: '🇸🇴'}, {name: 'South Africa', iso2: CountryISO.SouthAfrica, dialCode: '27', flag: '🇿🇦'}, + {name: 'South Georgia and the South Sandwich Islands', + iso2: CountryISO.SouthGeorgiaAndTheSouthSandwichIslands, dialCode: '500', flag: '🇬🇸'}, {name: 'South Korea', iso2: CountryISO.SouthKorea, dialCode: '82', flag: '🇰🇷'}, {name: 'South Sudan', iso2: CountryISO.SouthSudan, dialCode: '211', flag: '🇸🇸'}, - {name: 'Spain', iso2: CountryISO.Spain, dialCode: '34', flag: '🇪🇸'}, + {name: 'Spain', iso2: CountryISO.Spain, dialCode: '34', flag: '🇪🇸', postCodePattern: /((0[1-9]|5[0-2])|[1-4][0-9])[0-9]{3}/}, {name: 'Sri Lanka', iso2: CountryISO.SriLanka, dialCode: '94', flag: '🇱🇰'}, {name: 'Sudan', iso2: CountryISO.Sudan, dialCode: '249', flag: '🇸🇩'}, - {name: 'Suriname: ', iso2: CountryISO.Suriname, dialCode: '597', flag: '🇸🇷'}, + {name: 'Suriname', iso2: CountryISO.Suriname, dialCode: '597', flag: '🇸🇷'}, {name: 'Svalbard and Jan Mayen', iso2: CountryISO.SvalbardAndJanMayen, dialCode: '47', flag: '🇸🇯'}, {name: 'Swaziland', iso2: CountryISO.Swaziland, dialCode: '268', flag: '🇸🇿'}, - {name: 'Sweden', iso2: CountryISO.Sweden, dialCode: '46', flag: '🇸🇪'}, + {name: 'Sweden', iso2: CountryISO.Sweden, dialCode: '46', flag: '🇸🇪', postCodePattern: /\d{3}\s?\d{2}/}, {name: 'Switzerland', iso2: CountryISO.Switzerland, dialCode: '41', flag: '🇨🇭'}, - {name: 'Syria', iso2: CountryISO.Syria, dialCode: '963', flag: '🇸🇾'}, + {name: 'Syrian Arab Republic', iso2: CountryISO.Syria, dialCode: '963', flag: '🇸🇾'}, {name: 'Taiwan', iso2: CountryISO.Taiwan, dialCode: '886', flag: '🇹🇼'}, {name: 'Tajikistan', iso2: CountryISO.Tajikistan, dialCode: '992', flag: '🇹🇯'}, - {name: 'Tanzania', iso2: CountryISO.Tanzania, dialCode: '255', flag: '🇹🇿'}, + {name: 'Tanzania, United Republic of', iso2: CountryISO.Tanzania, dialCode: '255', flag: '🇹🇿'}, {name: 'Thailand', iso2: CountryISO.Thailand, dialCode: '66', flag: '🇹🇭'}, {name: 'Timor-Leste', iso2: CountryISO.TimorLeste, dialCode: '670', flag: '🇹🇱'}, {name: 'Togo', iso2: CountryISO.Togo, dialCode: '228', flag: '🇹🇬'}, @@ -502,8 +519,8 @@ export class CountryData { {name: 'Uganda', iso2: CountryISO.Uganda, dialCode: '256', flag: '🇺🇬'}, {name: 'Ukraine', iso2: CountryISO.Ukraine, dialCode: '380', flag: '🇺🇦'}, {name: 'United Arab Emirates', iso2: CountryISO.UnitedArabEmirates, dialCode: '971', flag: '🇦🇪'}, - {name: 'United Kingdom', iso2: CountryISO.UnitedKingdom, dialCode: '44', flag: '🇬🇧'}, - {name: 'United States', iso2: CountryISO.UnitedStates, dialCode: '1', flag: '🇺🇸'}, + {name: 'United Kingdom', iso2: CountryISO.UnitedKingdom, dialCode: '44', flag: '🇬🇧', postCodePattern: /[A-Za-z]{1,2}[0-9Rr][0-9A-Za-z]? [0-9][ABD-HJLNP-UW-Zabd-hjlnp-uw-z]{2}/}, + {name: 'United States', iso2: CountryISO.UnitedStates, dialCode: '1', flag: '🇺🇸', postCodePattern: /(\d{5}(-\d{4})?)/}, {name: 'Uruguay', iso2: CountryISO.Uruguay, dialCode: '598', flag: '🇺🇾'}, {name: 'Uzbekistan', iso2: CountryISO.Uzbekistan, dialCode: '998', flag: '🇺🇿'}, {name: 'Vanuatu', iso2: CountryISO.Vanuatu, dialCode: '678', flag: '🇻🇺'}, @@ -515,6 +532,7 @@ export class CountryData { {name: 'Yemen', iso2: CountryISO.Yemen, dialCode: '967', flag: '🇾🇪'}, {name: 'Zambia', iso2: CountryISO.Zambia, dialCode: '260', flag: '🇿🇲'}, {name: 'Zimbabwe', iso2: CountryISO.Zimbabwe, dialCode: '263', flag: '🇿🇼'}, - {name: 'Åland Islands', iso2: CountryISO.ÅlandIslands, dialCode: '358', flag: '🇦🇽'} + {name: 'Åland Islands', iso2: CountryISO.AlandIslands, dialCode: '358', flag: '🇦🇽'} ]; } +/* eslint-enable max-len */ diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index 3d4edacd1d..21c912edf5 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -222,6 +222,7 @@ import { WidgetButtonComponent } from '@shared/components/button/widget-button.c import { HexInputComponent } from '@shared/components/color-picker/hex-input.component'; import { CustomTranslatePipe } from '@shared/pipe/custom-translate.pipe'; import { ScadaSymbolInputComponent } from '@shared/components/image/scada-symbol-input.component'; +import { CountryAutocompleteComponent } from '@shared/components/country-autocomplete.component'; export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) { return markedOptionsService; @@ -383,6 +384,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) TogglePasswordComponent, ProtobufContentComponent, BranchAutocompleteComponent, + CountryAutocompleteComponent, PhoneInputComponent, TbScriptLangComponent, NotificationComponent, @@ -640,6 +642,7 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) TogglePasswordComponent, ProtobufContentComponent, BranchAutocompleteComponent, + CountryAutocompleteComponent, PhoneInputComponent, TbScriptLangComponent, NotificationComponent, 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 f873650b26..4dd7125f72 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -994,6 +994,7 @@ }, "contact": { "country": "Country", + "country-required": "Country is required.", "city": "City", "state": "State / Province", "postal-code": "Zip / Postal Code", @@ -1003,6 +1004,8 @@ "phone": "Phone", "email": "Email", "no-address": "No address", + "no-country-found": "No countries found.", + "no-country-matching": "No country matching '{{country}}' were found.", "state-max-length": "State length should be less than 256", "phone-max-length": "Phone number should be less than 256", "city-max-length": "Specified city should be less than 256"