diff --git a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts index e0ff482fc6..103aad6da2 100644 --- a/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts +++ b/npm/ng-packs/packages/core/src/lib/services/config-state.service.ts @@ -14,18 +14,16 @@ import { InternalStore } from '../utils/internal-store-utils'; providedIn: 'root', }) export class ConfigStateService { + private updateSubject = new Subject(); private readonly store = new InternalStore({} as ApplicationConfigurationDto); - - setState(config: ApplicationConfigurationDto){ - this.store.set(config) + + setState(config: ApplicationConfigurationDto) { + this.store.set(config); } get createOnUpdateStream() { return this.store.sliceUpdate; } - - private updateSubject = new Subject(); - constructor( private abpConfigService: AbpApplicationConfigurationService, private abpApplicationLocalizationService: AbpApplicationLocalizationService, @@ -228,4 +226,4 @@ function splitKeys(keys: string[] | string): string[] { } return keys; -} \ No newline at end of file +} diff --git a/npm/ng-packs/packages/core/src/lib/tests/validators.spec.ts b/npm/ng-packs/packages/core/src/lib/tests/validators.spec.ts index 6bc33dbfda..695625b740 100644 --- a/npm/ng-packs/packages/core/src/lib/tests/validators.spec.ts +++ b/npm/ng-packs/packages/core/src/lib/tests/validators.spec.ts @@ -5,6 +5,7 @@ import { validateCreditCard } from '../validators/credit-card.validator'; import { validateRequired } from '../validators/required.validator'; import { validateStringLength } from '../validators/string-length.validator'; import { validateUrl } from '../validators/url.validator'; +import { validateUniqueCharacter } from '../validators'; const emailAddress = () => Validators.email; @@ -181,4 +182,25 @@ describe('Validators', () => { expect(control.errors).toEqual(expected); }); }); + + describe('Unique Character Validator', () => { + const error = { uniqueCharacter: true }; + + test.each` + input | expected + ${undefined} | ${null} + ${null} | ${null} + ${''} | ${null} + ${'password'} | ${error} + ${'123456789'} | ${null} + ${'1q2w3E*'} | ${null} + ${'password123'} | ${error} + `('should return $expected when input is $input', ({ input, expected }) => { + const control = new FormControl(input, [validateUniqueCharacter()]); + control.markAsDirty({ onlySelf: true }); + control.updateValueAndValidity({ onlySelf: true, emitEvent: false }); + + expect(control.errors).toEqual(expected); + }); + }); }); diff --git a/npm/ng-packs/packages/core/src/lib/validators/index.ts b/npm/ng-packs/packages/core/src/lib/validators/index.ts index 69880dbf84..496cbb1f40 100644 --- a/npm/ng-packs/packages/core/src/lib/validators/index.ts +++ b/npm/ng-packs/packages/core/src/lib/validators/index.ts @@ -4,15 +4,18 @@ import { validateCreditCard } from './credit-card.validator'; import { validateRange } from './range.validator'; import { validateRequired } from './required.validator'; import { validateStringLength } from './string-length.validator'; +import { validateUniqueCharacter } from './unique-character.validator'; import { validateUrl } from './url.validator'; import { validateUsername } from './username.validator'; +export { validateUniqueCharacter } from './unique-character.validator'; + export * from './age.validator'; export * from './credit-card.validator'; export * from './range.validator'; export * from './required.validator'; export * from './string-length.validator'; export * from './url.validator'; - +export * from './unique-character.validator'; export const AbpValidators = { creditCard: validateCreditCard, emailAddress: () => Validators.email, @@ -22,4 +25,5 @@ export const AbpValidators = { stringLength: validateStringLength, url: validateUrl, username: validateUsername, + uniqueCharacter: validateUniqueCharacter, }; diff --git a/npm/ng-packs/packages/core/src/lib/validators/unique-character.validator.ts b/npm/ng-packs/packages/core/src/lib/validators/unique-character.validator.ts new file mode 100644 index 0000000000..509dc66c7f --- /dev/null +++ b/npm/ng-packs/packages/core/src/lib/validators/unique-character.validator.ts @@ -0,0 +1,20 @@ +import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms'; +import { isNullOrEmpty } from '../utils'; + +export interface UniqueCharacterError { + uniqueCharacter: true; +} + +export function validateUniqueCharacter(): ValidatorFn { + return (control: AbstractControl): UniqueCharacterError | null => { + if (isNullOrEmpty(control.value)) return null; + + return isUnqiueCharacter(control.value) ? null : { uniqueCharacter: true }; + }; +} + +function isUnqiueCharacter(value: string): boolean { + const set = new Set(value.split('')); + + return set.size == value.length; +}