taxtank-core 0.30.0 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/forms/address/address.form.mjs +59 -41
- package/esm2020/lib/forms/phone/phone.form.mjs +3 -2
- package/esm2020/lib/forms/sole/sole-contact.form.mjs +2 -4
- package/esm2020/lib/validators/address-corelogic.validator.mjs +9 -8
- package/fesm2015/taxtank-core.mjs +239 -214
- package/fesm2015/taxtank-core.mjs.map +1 -1
- package/fesm2020/taxtank-core.mjs +238 -214
- package/fesm2020/taxtank-core.mjs.map +1 -1
- package/lib/forms/address/address.form.d.ts +13 -10
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import * as i1$2 from '@angular/common';
|
|
|
4
4
|
import { CommonModule, DatePipe } from '@angular/common';
|
|
5
5
|
import * as i1 from '@angular/common/http';
|
|
6
6
|
import { HttpParams, HttpErrorResponse, HTTP_INTERCEPTORS } from '@angular/common/http';
|
|
7
|
-
import { map, mergeMap, filter, catchError, take, switchMap, finalize, first as first$1, skip,
|
|
7
|
+
import { map, mergeMap, filter, catchError, take, switchMap, finalize, first as first$1, skip, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|
8
8
|
import { ReplaySubject, Subject, BehaviorSubject, throwError, Observable, of, combineLatest, forkJoin, from, merge as merge$1 } from 'rxjs';
|
|
9
9
|
import { plainToClass, Type, Exclude, Transform, Expose, classToPlain } from 'class-transformer';
|
|
10
10
|
import { JwtHelperService } from '@auth0/angular-jwt';
|
|
@@ -15761,187 +15761,19 @@ class AbstractForm extends UntypedFormGroup {
|
|
|
15761
15761
|
}
|
|
15762
15762
|
}
|
|
15763
15763
|
|
|
15764
|
-
/**
|
|
15765
|
-
* Check if at least one form field is true, otherwise form is invalid.
|
|
15766
|
-
* Use with groups of boolean form controls (checkbox, toggle, etc.)
|
|
15767
|
-
*/
|
|
15768
|
-
function atLeastOneCheckedValidator() {
|
|
15769
|
-
return (formGroup) => {
|
|
15770
|
-
return Object.values(formGroup.controls)
|
|
15771
|
-
.find((control) => control.value) ? null : { nothingChecked: true };
|
|
15772
|
-
};
|
|
15773
|
-
}
|
|
15774
|
-
|
|
15775
|
-
/**
|
|
15776
|
-
* Validation function for autocomplete fields. Checks that the user should select a value from a list rather than type in input field
|
|
15777
|
-
* @TODO Alex: create class AppValidators with static methods and move there all custom validators (line Angular Validators)
|
|
15778
|
-
*/
|
|
15779
|
-
function autocompleteValidator() {
|
|
15780
|
-
return (control) => {
|
|
15781
|
-
return (!control.value || (typeof control.value === 'object')) ? null : { notFromList: true };
|
|
15782
|
-
};
|
|
15783
|
-
}
|
|
15784
|
-
|
|
15785
|
-
function conditionalValidator(condition, validator) {
|
|
15786
|
-
return function (control) {
|
|
15787
|
-
revalidateOnChanges(control);
|
|
15788
|
-
if (control && control.parent) {
|
|
15789
|
-
if (condition(control.parent)) {
|
|
15790
|
-
return validator(control);
|
|
15791
|
-
}
|
|
15792
|
-
}
|
|
15793
|
-
return null;
|
|
15794
|
-
};
|
|
15795
|
-
}
|
|
15796
|
-
/**
|
|
15797
|
-
* Conditional validator depends on other fields and should be updated on each form value change
|
|
15798
|
-
*/
|
|
15799
|
-
function revalidateOnChanges(control) {
|
|
15800
|
-
if (control && control.parent && !control['_revalidateOnChanges']) {
|
|
15801
|
-
control['_revalidateOnChanges'] = true;
|
|
15802
|
-
control.parent.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
|
|
15803
|
-
.subscribe(() => {
|
|
15804
|
-
control.updateValueAndValidity({ emitEvent: false });
|
|
15805
|
-
});
|
|
15806
|
-
}
|
|
15807
|
-
return;
|
|
15808
|
-
}
|
|
15809
|
-
|
|
15810
|
-
/**
|
|
15811
|
-
* Regular expressions that are used to check password strength and valid values
|
|
15812
|
-
*/
|
|
15813
|
-
const PASSWORD_REGEXPS = {
|
|
15814
|
-
medium: /(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})/,
|
|
15815
|
-
strong: /(((?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]))|((?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]))|((?=.*[A-Z])(?=.*[0-9]))(?=.*[!@#$%^&*]))(?=.{8,})/,
|
|
15816
|
-
format: /^[0-9a-zA-Z!@$!%*?&#]*$/
|
|
15817
|
-
};
|
|
15818
|
-
function passwordValidator() {
|
|
15819
|
-
return (control) => {
|
|
15820
|
-
if (!PASSWORD_REGEXPS.format.test(control.value)) {
|
|
15821
|
-
return { passwordInvalid: true };
|
|
15822
|
-
}
|
|
15823
|
-
if (!PASSWORD_REGEXPS.medium.test(control.value)) {
|
|
15824
|
-
return { passwordWeak: true };
|
|
15825
|
-
}
|
|
15826
|
-
return null;
|
|
15827
|
-
};
|
|
15828
|
-
}
|
|
15829
|
-
|
|
15830
|
-
function passwordMatchValidator(newPassControlName, confirmPassControlName) {
|
|
15831
|
-
return (group) => {
|
|
15832
|
-
const passwordControl = group.get(newPassControlName);
|
|
15833
|
-
const confirmControl = group.get(confirmPassControlName);
|
|
15834
|
-
if (confirmControl.errors && !confirmControl.hasError('passwordMismatch')) {
|
|
15835
|
-
// return if another validator has already found an error on the confirmControl
|
|
15836
|
-
return this;
|
|
15837
|
-
}
|
|
15838
|
-
if (passwordControl.value !== confirmControl.value) {
|
|
15839
|
-
confirmControl.setErrors({ passwordMismatch: true });
|
|
15840
|
-
}
|
|
15841
|
-
else {
|
|
15842
|
-
confirmControl.setErrors(null);
|
|
15843
|
-
}
|
|
15844
|
-
};
|
|
15845
|
-
}
|
|
15846
|
-
|
|
15847
|
-
var MessagesEnum$1;
|
|
15848
|
-
(function (MessagesEnum) {
|
|
15849
|
-
MessagesEnum["INVALID_DATE"] = "The date should not be before $1";
|
|
15850
|
-
})(MessagesEnum$1 || (MessagesEnum$1 = {}));
|
|
15851
|
-
|
|
15852
|
-
/**
|
|
15853
|
-
* Validation function, that checks If date form value is more than provided date
|
|
15854
|
-
*/
|
|
15855
|
-
function minDateValidator(date, message = MessagesEnum$1.INVALID_DATE.replace('$1', new DatePipe('en-US').transform(date))) {
|
|
15856
|
-
return (control) => {
|
|
15857
|
-
if (!control.value) {
|
|
15858
|
-
return null;
|
|
15859
|
-
}
|
|
15860
|
-
// form control value can be as a Moment object - we wrap it in "new Date()" to work with it like with JS Date
|
|
15861
|
-
if (new Date(control.value) >= new Date(date)) {
|
|
15862
|
-
return null;
|
|
15863
|
-
}
|
|
15864
|
-
return { minDate: message };
|
|
15865
|
-
};
|
|
15866
|
-
}
|
|
15867
|
-
|
|
15868
|
-
/**
|
|
15869
|
-
* Validator that check if sum amount of provided fields is greater than provided sum
|
|
15870
|
-
* @param field to check in each formArray element
|
|
15871
|
-
* @param summary to compare with fields sum
|
|
15872
|
-
* @param fieldAlias to show it in error message
|
|
15873
|
-
*/
|
|
15874
|
-
function fieldsSumValidator(field, summary = 100, fieldAlias) {
|
|
15875
|
-
return (formArray) => {
|
|
15876
|
-
// calculate sum of desired fields in formArray control
|
|
15877
|
-
const fieldsSum = formArray['controls']
|
|
15878
|
-
.reduce((acc, group) => acc += group.get(field).value, 0);
|
|
15879
|
-
if (fieldsSum <= summary) {
|
|
15880
|
-
return null;
|
|
15881
|
-
}
|
|
15882
|
-
else {
|
|
15883
|
-
return {
|
|
15884
|
-
fieldsSum: {
|
|
15885
|
-
name: field,
|
|
15886
|
-
alias: fieldAlias,
|
|
15887
|
-
summary
|
|
15888
|
-
}
|
|
15889
|
-
};
|
|
15890
|
-
}
|
|
15891
|
-
};
|
|
15892
|
-
}
|
|
15893
|
-
|
|
15894
|
-
/**
|
|
15895
|
-
* Validation function, that checks If provided date is within a current financial year
|
|
15896
|
-
*/
|
|
15897
|
-
function currentFinYearValidator() {
|
|
15898
|
-
const currentFinYear = new FinancialYear();
|
|
15899
|
-
return (control) => {
|
|
15900
|
-
if (!control.value || control.value >= currentFinYear.startDate && control.value <= currentFinYear.endDate) {
|
|
15901
|
-
return null;
|
|
15902
|
-
}
|
|
15903
|
-
return { notCurrentFinYear: true };
|
|
15904
|
-
};
|
|
15905
|
-
}
|
|
15906
|
-
|
|
15907
|
-
const MAX_SIZE = 4194304;
|
|
15908
|
-
class FileValidator {
|
|
15909
|
-
// File max size check
|
|
15910
|
-
static fileMaxSize(maxSize = MAX_SIZE) {
|
|
15911
|
-
const validatorFn = (file) => {
|
|
15912
|
-
return file.size > maxSize ? { fileMaxSize: { maxSize } } : null;
|
|
15913
|
-
};
|
|
15914
|
-
return FileValidator.fileValidation(validatorFn);
|
|
15915
|
-
}
|
|
15916
|
-
// File extension check
|
|
15917
|
-
static fileExtensions(allowedExtensions = DOCUMENT_FILE_TYPES.all) {
|
|
15918
|
-
const validatorFn = (file) => {
|
|
15919
|
-
return allowedExtensions.includes(file.type) ? null : { fileExtension: { allowedExtensions: allowedExtensions.join() } };
|
|
15920
|
-
};
|
|
15921
|
-
return FileValidator.fileValidation(validatorFn);
|
|
15922
|
-
}
|
|
15923
|
-
static fileValidation(validatorFn) {
|
|
15924
|
-
return (formControl) => {
|
|
15925
|
-
if (!formControl.value) {
|
|
15926
|
-
return null;
|
|
15927
|
-
}
|
|
15928
|
-
return validatorFn(formControl.value);
|
|
15929
|
-
};
|
|
15930
|
-
}
|
|
15931
|
-
}
|
|
15932
|
-
|
|
15933
15764
|
/**
|
|
15934
15765
|
* Validator for address, check if corelogic suggestion selected correctly
|
|
15935
15766
|
*/
|
|
15936
15767
|
function addressCorelogicValidator() {
|
|
15937
15768
|
return (form) => {
|
|
15938
|
-
|
|
15939
|
-
|
|
15940
|
-
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
|
|
15769
|
+
// we are interested in corelogic ids only for Australian addresses
|
|
15770
|
+
if (!form.isAustraliaSelected()) {
|
|
15771
|
+
return null;
|
|
15772
|
+
}
|
|
15773
|
+
// we need at least corelogic locality id to get growth percent
|
|
15774
|
+
const locIdControl = form.get('corelogicLocId');
|
|
15775
|
+
if (locIdControl.enabled && locIdControl.hasError('required')) {
|
|
15776
|
+
return { address: 'City, state or postal code not specified' };
|
|
15945
15777
|
}
|
|
15946
15778
|
return null;
|
|
15947
15779
|
};
|
|
@@ -15951,51 +15783,49 @@ function addressCorelogicValidator() {
|
|
|
15951
15783
|
* Address form. Works with corelogic or manual address
|
|
15952
15784
|
*/
|
|
15953
15785
|
class AddressForm extends AbstractForm {
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
|
|
15958
|
-
*/
|
|
15959
|
-
constructor(address = plainToClass(Address, {}), isCorelogicRequired = false) {
|
|
15786
|
+
constructor(
|
|
15787
|
+
// no default value because Address form is always a child form. That's mean address value always passed and then default value never work.
|
|
15788
|
+
// even if null passed, default value will not work
|
|
15789
|
+
address) {
|
|
15960
15790
|
super({
|
|
15961
15791
|
// prefill search input with address string for edit case
|
|
15962
|
-
searchQuery: new UntypedFormControl(address
|
|
15963
|
-
type: new UntypedFormControl(address
|
|
15964
|
-
//
|
|
15965
|
-
corelogicLocId: new UntypedFormControl(address.
|
|
15966
|
-
corelogicRefId: new UntypedFormControl(address
|
|
15967
|
-
// manual fields
|
|
15968
|
-
unitNumber: new UntypedFormControl({ value: address
|
|
15969
|
-
address: new UntypedFormControl({ value: address
|
|
15970
|
-
streetNumber: new UntypedFormControl({ value: address
|
|
15971
|
-
street: new UntypedFormControl({ value: address
|
|
15972
|
-
city: new UntypedFormControl({ value: address
|
|
15973
|
-
state: new UntypedFormControl({ value: address
|
|
15974
|
-
postcode: new UntypedFormControl({ value: address
|
|
15975
|
-
country: new UntypedFormControl({ value: address
|
|
15792
|
+
searchQuery: new UntypedFormControl(address?.address ? address.nameLong : null, Validators.required),
|
|
15793
|
+
type: new UntypedFormControl(address?.type || AddressTypeEnum.STREET, Validators.required),
|
|
15794
|
+
// corelogic fields (required for Australia and disabled for other countries)
|
|
15795
|
+
corelogicLocId: new UntypedFormControl({ value: address?.corelogicLocId, disabled: true }, Validators.required),
|
|
15796
|
+
corelogicRefId: new UntypedFormControl({ value: address?.corelogicRefId, disabled: true }),
|
|
15797
|
+
// manual fields (using when address not found in corelogic)
|
|
15798
|
+
unitNumber: new UntypedFormControl({ value: address?.unitNumber, disabled: true }),
|
|
15799
|
+
address: new UntypedFormControl({ value: address?.address, disabled: true }, Validators.required),
|
|
15800
|
+
streetNumber: new UntypedFormControl({ value: address?.streetNumber, disabled: true }, [Validators.required, Validators.pattern(AddressForm.streetNumberPattern)]),
|
|
15801
|
+
street: new UntypedFormControl({ value: address?.street, disabled: true }, Validators.required),
|
|
15802
|
+
city: new UntypedFormControl({ value: address?.city, disabled: true }, Validators.required),
|
|
15803
|
+
state: new UntypedFormControl({ value: address?.state, disabled: true }, Validators.required),
|
|
15804
|
+
postcode: new UntypedFormControl({ value: address?.postcode, disabled: true }, Validators.required),
|
|
15805
|
+
country: new UntypedFormControl({ value: address?.country || Country.australia, disabled: true }, Validators.required)
|
|
15976
15806
|
}, address, addressCorelogicValidator());
|
|
15977
|
-
this.isCorelogicRequired = isCorelogicRequired;
|
|
15978
15807
|
/**
|
|
15979
15808
|
* Emit event to search address in corelogic when user filled enough data for corelogic
|
|
15980
15809
|
*/
|
|
15981
15810
|
this.onSearch = new EventEmitter();
|
|
15811
|
+
if (this.isAustraliaSelected()) {
|
|
15812
|
+
this.enableCorelogicFields();
|
|
15813
|
+
}
|
|
15982
15814
|
this.listenEvents();
|
|
15983
15815
|
}
|
|
15984
15816
|
/**
|
|
15985
15817
|
* Get search query for corelogic location search based on manual fields values
|
|
15986
15818
|
*/
|
|
15987
15819
|
get manualSearchQuery() {
|
|
15988
|
-
|
|
15820
|
+
// nothing to search when manual fields are invalid or when selected country is not Australia because we don't need to use corelogic for other countries
|
|
15821
|
+
if (!this.isManualSearchAvailable() || !this.isAustraliaSelected()) {
|
|
15989
15822
|
return '';
|
|
15990
15823
|
}
|
|
15991
|
-
|
|
15824
|
+
// for manual mode we search corelogic for city (location) and ignore street
|
|
15825
|
+
return `${this.get('city').value} ${this.get('state').value} ${this.get('postcode').value}`;
|
|
15992
15826
|
}
|
|
15993
15827
|
listenEvents() {
|
|
15994
15828
|
this.listenSearchQueryChanges();
|
|
15995
|
-
// no need to search corelogic locality when corelogic is not required
|
|
15996
|
-
if (this.isCorelogicRequired) {
|
|
15997
|
-
this.listenManualFieldsChanges();
|
|
15998
|
-
}
|
|
15999
15829
|
}
|
|
16000
15830
|
/**
|
|
16001
15831
|
* Handle corelogic suggestion select
|
|
@@ -16011,25 +15841,29 @@ class AddressForm extends AbstractForm {
|
|
|
16011
15841
|
corelogicRefId: suggestion.propertyId
|
|
16012
15842
|
});
|
|
16013
15843
|
}
|
|
15844
|
+
/**
|
|
15845
|
+
* Check if Australia is selected in country field
|
|
15846
|
+
*/
|
|
15847
|
+
isAustraliaSelected() {
|
|
15848
|
+
return this.get('country').value?.id === Country.australia.id;
|
|
15849
|
+
}
|
|
16014
15850
|
/**
|
|
16015
15851
|
* Enable manual mode
|
|
16016
15852
|
*/
|
|
16017
15853
|
switchToManual() {
|
|
16018
15854
|
this.isManual = true;
|
|
16019
15855
|
this.get('searchQuery').disable();
|
|
15856
|
+
this.get('unitNumber').enable();
|
|
16020
15857
|
this.get('address').enable();
|
|
16021
15858
|
this.get('streetNumber').enable();
|
|
16022
15859
|
this.get('street').enable();
|
|
16023
|
-
this.get('unitNumber').enable();
|
|
16024
15860
|
this.get('city').enable();
|
|
16025
15861
|
this.get('state').enable();
|
|
16026
15862
|
this.get('postcode').enable();
|
|
16027
|
-
|
|
16028
|
-
|
|
16029
|
-
this.get('corelogicLocId').disable();
|
|
16030
|
-
this.get('corelogicRefId').disable();
|
|
16031
|
-
}
|
|
15863
|
+
this.get('country').enable();
|
|
15864
|
+
this.listenManualFieldsChanges();
|
|
16032
15865
|
this.listenStreetFieldsChanges();
|
|
15866
|
+
this.listenCountryChanges();
|
|
16033
15867
|
}
|
|
16034
15868
|
/**
|
|
16035
15869
|
* Emit event to search address in corelogic when search field changes
|
|
@@ -16061,7 +15895,7 @@ class AddressForm extends AbstractForm {
|
|
|
16061
15895
|
* Check if all fields required for manual corelogic search are filled before request sending
|
|
16062
15896
|
*/
|
|
16063
15897
|
isManualSearchAvailable() {
|
|
16064
|
-
return this.get('
|
|
15898
|
+
return this.get('city').valid && this.get('state').valid && this.get('postcode').valid;
|
|
16065
15899
|
}
|
|
16066
15900
|
/**
|
|
16067
15901
|
* When corelogic is required we have to search address even for manual address
|
|
@@ -16073,7 +15907,7 @@ class AddressForm extends AbstractForm {
|
|
|
16073
15907
|
// delay to avoid search request for each value change
|
|
16074
15908
|
debounceTime(AddressForm.searchDelay),
|
|
16075
15909
|
// do nothing when not all required fields filled
|
|
16076
|
-
filter(() => this.isManualSearchAvailable()), map(() => this.manualSearchQuery),
|
|
15910
|
+
filter(() => this.isManualSearchAvailable() && this.isAustraliaSelected()), map(() => this.manualSearchQuery),
|
|
16077
15911
|
// skip when value not changed
|
|
16078
15912
|
distinctUntilChanged())
|
|
16079
15913
|
.subscribe(() => {
|
|
@@ -16091,6 +15925,26 @@ class AddressForm extends AbstractForm {
|
|
|
16091
15925
|
this.get('address').setValue(`${this.get('streetNumber').value} ${this.get('street').value}`);
|
|
16092
15926
|
});
|
|
16093
15927
|
}
|
|
15928
|
+
enableCorelogicFields() {
|
|
15929
|
+
this.get('corelogicLocId').enable();
|
|
15930
|
+
this.get('corelogicRefId').enable();
|
|
15931
|
+
}
|
|
15932
|
+
disableCorelogicFields() {
|
|
15933
|
+
this.get('corelogicLocId').disable();
|
|
15934
|
+
this.get('corelogicRefId').disable();
|
|
15935
|
+
}
|
|
15936
|
+
/**
|
|
15937
|
+
* Corelogic loc id is required for Australian addresses
|
|
15938
|
+
*/
|
|
15939
|
+
listenCountryChanges() {
|
|
15940
|
+
this.get('country').valueChanges.subscribe(() => {
|
|
15941
|
+
if (this.isAustraliaSelected()) {
|
|
15942
|
+
this.enableCorelogicFields();
|
|
15943
|
+
return;
|
|
15944
|
+
}
|
|
15945
|
+
this.disableCorelogicFields();
|
|
15946
|
+
});
|
|
15947
|
+
}
|
|
16094
15948
|
}
|
|
16095
15949
|
/**
|
|
16096
15950
|
* Min search query required length
|
|
@@ -16186,6 +16040,175 @@ class LoanForm extends AbstractForm {
|
|
|
16186
16040
|
}
|
|
16187
16041
|
LoanForm.mortgageLoanTypes = [LoanTypeEnum.MORTGAGE, LoanTypeEnum.HOME_EQUITY_LINE_OF_CREDIT, LoanTypeEnum.HOME_LOAN];
|
|
16188
16042
|
|
|
16043
|
+
/**
|
|
16044
|
+
* Check if at least one form field is true, otherwise form is invalid.
|
|
16045
|
+
* Use with groups of boolean form controls (checkbox, toggle, etc.)
|
|
16046
|
+
*/
|
|
16047
|
+
function atLeastOneCheckedValidator() {
|
|
16048
|
+
return (formGroup) => {
|
|
16049
|
+
return Object.values(formGroup.controls)
|
|
16050
|
+
.find((control) => control.value) ? null : { nothingChecked: true };
|
|
16051
|
+
};
|
|
16052
|
+
}
|
|
16053
|
+
|
|
16054
|
+
/**
|
|
16055
|
+
* Validation function for autocomplete fields. Checks that the user should select a value from a list rather than type in input field
|
|
16056
|
+
* @TODO Alex: create class AppValidators with static methods and move there all custom validators (line Angular Validators)
|
|
16057
|
+
*/
|
|
16058
|
+
function autocompleteValidator() {
|
|
16059
|
+
return (control) => {
|
|
16060
|
+
return (!control.value || (typeof control.value === 'object')) ? null : { notFromList: true };
|
|
16061
|
+
};
|
|
16062
|
+
}
|
|
16063
|
+
|
|
16064
|
+
function conditionalValidator(condition, validator) {
|
|
16065
|
+
return function (control) {
|
|
16066
|
+
revalidateOnChanges(control);
|
|
16067
|
+
if (control && control.parent) {
|
|
16068
|
+
if (condition(control.parent)) {
|
|
16069
|
+
return validator(control);
|
|
16070
|
+
}
|
|
16071
|
+
}
|
|
16072
|
+
return null;
|
|
16073
|
+
};
|
|
16074
|
+
}
|
|
16075
|
+
/**
|
|
16076
|
+
* Conditional validator depends on other fields and should be updated on each form value change
|
|
16077
|
+
*/
|
|
16078
|
+
function revalidateOnChanges(control) {
|
|
16079
|
+
if (control && control.parent && !control['_revalidateOnChanges']) {
|
|
16080
|
+
control['_revalidateOnChanges'] = true;
|
|
16081
|
+
control.parent.valueChanges.pipe(distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)))
|
|
16082
|
+
.subscribe(() => {
|
|
16083
|
+
control.updateValueAndValidity({ emitEvent: false });
|
|
16084
|
+
});
|
|
16085
|
+
}
|
|
16086
|
+
return;
|
|
16087
|
+
}
|
|
16088
|
+
|
|
16089
|
+
/**
|
|
16090
|
+
* Regular expressions that are used to check password strength and valid values
|
|
16091
|
+
*/
|
|
16092
|
+
const PASSWORD_REGEXPS = {
|
|
16093
|
+
medium: /(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})/,
|
|
16094
|
+
strong: /(((?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]))|((?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*]))|((?=.*[A-Z])(?=.*[0-9]))(?=.*[!@#$%^&*]))(?=.{8,})/,
|
|
16095
|
+
format: /^[0-9a-zA-Z!@$!%*?&#]*$/
|
|
16096
|
+
};
|
|
16097
|
+
function passwordValidator() {
|
|
16098
|
+
return (control) => {
|
|
16099
|
+
if (!PASSWORD_REGEXPS.format.test(control.value)) {
|
|
16100
|
+
return { passwordInvalid: true };
|
|
16101
|
+
}
|
|
16102
|
+
if (!PASSWORD_REGEXPS.medium.test(control.value)) {
|
|
16103
|
+
return { passwordWeak: true };
|
|
16104
|
+
}
|
|
16105
|
+
return null;
|
|
16106
|
+
};
|
|
16107
|
+
}
|
|
16108
|
+
|
|
16109
|
+
function passwordMatchValidator(newPassControlName, confirmPassControlName) {
|
|
16110
|
+
return (group) => {
|
|
16111
|
+
const passwordControl = group.get(newPassControlName);
|
|
16112
|
+
const confirmControl = group.get(confirmPassControlName);
|
|
16113
|
+
if (confirmControl.errors && !confirmControl.hasError('passwordMismatch')) {
|
|
16114
|
+
// return if another validator has already found an error on the confirmControl
|
|
16115
|
+
return this;
|
|
16116
|
+
}
|
|
16117
|
+
if (passwordControl.value !== confirmControl.value) {
|
|
16118
|
+
confirmControl.setErrors({ passwordMismatch: true });
|
|
16119
|
+
}
|
|
16120
|
+
else {
|
|
16121
|
+
confirmControl.setErrors(null);
|
|
16122
|
+
}
|
|
16123
|
+
};
|
|
16124
|
+
}
|
|
16125
|
+
|
|
16126
|
+
var MessagesEnum$1;
|
|
16127
|
+
(function (MessagesEnum) {
|
|
16128
|
+
MessagesEnum["INVALID_DATE"] = "The date should not be before $1";
|
|
16129
|
+
})(MessagesEnum$1 || (MessagesEnum$1 = {}));
|
|
16130
|
+
|
|
16131
|
+
/**
|
|
16132
|
+
* Validation function, that checks If date form value is more than provided date
|
|
16133
|
+
*/
|
|
16134
|
+
function minDateValidator(date, message = MessagesEnum$1.INVALID_DATE.replace('$1', new DatePipe('en-US').transform(date))) {
|
|
16135
|
+
return (control) => {
|
|
16136
|
+
if (!control.value) {
|
|
16137
|
+
return null;
|
|
16138
|
+
}
|
|
16139
|
+
// form control value can be as a Moment object - we wrap it in "new Date()" to work with it like with JS Date
|
|
16140
|
+
if (new Date(control.value) >= new Date(date)) {
|
|
16141
|
+
return null;
|
|
16142
|
+
}
|
|
16143
|
+
return { minDate: message };
|
|
16144
|
+
};
|
|
16145
|
+
}
|
|
16146
|
+
|
|
16147
|
+
/**
|
|
16148
|
+
* Validator that check if sum amount of provided fields is greater than provided sum
|
|
16149
|
+
* @param field to check in each formArray element
|
|
16150
|
+
* @param summary to compare with fields sum
|
|
16151
|
+
* @param fieldAlias to show it in error message
|
|
16152
|
+
*/
|
|
16153
|
+
function fieldsSumValidator(field, summary = 100, fieldAlias) {
|
|
16154
|
+
return (formArray) => {
|
|
16155
|
+
// calculate sum of desired fields in formArray control
|
|
16156
|
+
const fieldsSum = formArray['controls']
|
|
16157
|
+
.reduce((acc, group) => acc += group.get(field).value, 0);
|
|
16158
|
+
if (fieldsSum <= summary) {
|
|
16159
|
+
return null;
|
|
16160
|
+
}
|
|
16161
|
+
else {
|
|
16162
|
+
return {
|
|
16163
|
+
fieldsSum: {
|
|
16164
|
+
name: field,
|
|
16165
|
+
alias: fieldAlias,
|
|
16166
|
+
summary
|
|
16167
|
+
}
|
|
16168
|
+
};
|
|
16169
|
+
}
|
|
16170
|
+
};
|
|
16171
|
+
}
|
|
16172
|
+
|
|
16173
|
+
/**
|
|
16174
|
+
* Validation function, that checks If provided date is within a current financial year
|
|
16175
|
+
*/
|
|
16176
|
+
function currentFinYearValidator() {
|
|
16177
|
+
const currentFinYear = new FinancialYear();
|
|
16178
|
+
return (control) => {
|
|
16179
|
+
if (!control.value || control.value >= currentFinYear.startDate && control.value <= currentFinYear.endDate) {
|
|
16180
|
+
return null;
|
|
16181
|
+
}
|
|
16182
|
+
return { notCurrentFinYear: true };
|
|
16183
|
+
};
|
|
16184
|
+
}
|
|
16185
|
+
|
|
16186
|
+
const MAX_SIZE = 4194304;
|
|
16187
|
+
class FileValidator {
|
|
16188
|
+
// File max size check
|
|
16189
|
+
static fileMaxSize(maxSize = MAX_SIZE) {
|
|
16190
|
+
const validatorFn = (file) => {
|
|
16191
|
+
return file.size > maxSize ? { fileMaxSize: { maxSize } } : null;
|
|
16192
|
+
};
|
|
16193
|
+
return FileValidator.fileValidation(validatorFn);
|
|
16194
|
+
}
|
|
16195
|
+
// File extension check
|
|
16196
|
+
static fileExtensions(allowedExtensions = DOCUMENT_FILE_TYPES.all) {
|
|
16197
|
+
const validatorFn = (file) => {
|
|
16198
|
+
return allowedExtensions.includes(file.type) ? null : { fileExtension: { allowedExtensions: allowedExtensions.join() } };
|
|
16199
|
+
};
|
|
16200
|
+
return FileValidator.fileValidation(validatorFn);
|
|
16201
|
+
}
|
|
16202
|
+
static fileValidation(validatorFn) {
|
|
16203
|
+
return (formControl) => {
|
|
16204
|
+
if (!formControl.value) {
|
|
16205
|
+
return null;
|
|
16206
|
+
}
|
|
16207
|
+
return validatorFn(formControl.value);
|
|
16208
|
+
};
|
|
16209
|
+
}
|
|
16210
|
+
}
|
|
16211
|
+
|
|
16189
16212
|
/**
|
|
16190
16213
|
* Form array with bank account properties
|
|
16191
16214
|
* @TODO create AbstractFormArray
|
|
@@ -16401,7 +16424,7 @@ class SoleContactForm extends AbstractForm {
|
|
|
16401
16424
|
lastName: new UntypedFormControl(contact.lastName, Validators.required),
|
|
16402
16425
|
email: new UntypedFormControl(contact.email, [Validators.required, Validators.email]),
|
|
16403
16426
|
phone: new UntypedFormControl(contact.phone),
|
|
16404
|
-
address: new
|
|
16427
|
+
address: new UntypedFormControl(contact.address)
|
|
16405
16428
|
}, contact);
|
|
16406
16429
|
}
|
|
16407
16430
|
}
|
|
@@ -16890,7 +16913,8 @@ function phoneNumberValidator() {
|
|
|
16890
16913
|
|
|
16891
16914
|
class PhoneForm extends AbstractForm {
|
|
16892
16915
|
constructor(
|
|
16893
|
-
// no default value because
|
|
16916
|
+
// no default value because Address form is always a child form. That's mean address value always passed and then default value never work.
|
|
16917
|
+
// even if null passed, default value will not work
|
|
16894
16918
|
phone) {
|
|
16895
16919
|
super({
|
|
16896
16920
|
type: new UntypedFormControl(phone?.type || PhoneTypeEnum.MOBILE, Validators.required),
|