mirror of
https://github.com/bitwarden/browser
synced 2025-12-14 07:13:32 +00:00
Improve SSO Config validation (#572)
* Extract SsoConfig enums to own file * Add ChangeStripSpaces directive * Move custom validators to jslib * Add a11y-invalid directive * Add and implement dirtyValidators * Create ssoConfigView model and factory methods * Add interface for select options * Don't build SsoConfigData if null Co-authored-by: Oscar Hinton <oscar@oscarhinton.com>
This commit is contained in:
26
angular/src/directives/a11y-invalid.directive.ts
Normal file
26
angular/src/directives/a11y-invalid.directive.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Directive, ElementRef, OnDestroy, OnInit } from "@angular/core";
|
||||
import { NgControl } from "@angular/forms";
|
||||
import { Subscription } from "rxjs";
|
||||
|
||||
@Directive({
|
||||
selector: "[appA11yInvalid]",
|
||||
})
|
||||
export class A11yInvalidDirective implements OnDestroy, OnInit {
|
||||
private sub: Subscription;
|
||||
|
||||
constructor(private el: ElementRef<HTMLInputElement>, private formControlDirective: NgControl) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.sub = this.formControlDirective.control.statusChanges.subscribe((status) => {
|
||||
if (status === "INVALID") {
|
||||
this.el.nativeElement.setAttribute("aria-invalid", "true");
|
||||
} else if (status === "VALID") {
|
||||
this.el.nativeElement.setAttribute("aria-invalid", "false");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.sub?.unsubscribe();
|
||||
}
|
||||
}
|
||||
12
angular/src/directives/input-strip-spaces.directive.ts
Normal file
12
angular/src/directives/input-strip-spaces.directive.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Directive, ElementRef, HostListener } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "input[appInputStripSpaces]",
|
||||
})
|
||||
export class InputStripSpacesDirective {
|
||||
constructor(private el: ElementRef<HTMLInputElement>) {}
|
||||
|
||||
@HostListener("input") onInput() {
|
||||
this.el.nativeElement.value = this.el.nativeElement.value.replace(/ /g, "");
|
||||
}
|
||||
}
|
||||
5
angular/src/interfaces/selectOptions.ts
Normal file
5
angular/src/interfaces/selectOptions.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export interface SelectOptions {
|
||||
name: string;
|
||||
value: any;
|
||||
disabled?: boolean;
|
||||
}
|
||||
25
angular/src/validators/dirty.validator.ts
Normal file
25
angular/src/validators/dirty.validator.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from "@angular/forms";
|
||||
import { requiredIf } from "./requiredIf.validator";
|
||||
|
||||
/**
|
||||
* A higher order function that takes a ValidatorFn and returns a new validator.
|
||||
* The new validator only runs the ValidatorFn if the control is dirty. This prevents error messages from being
|
||||
* displayed to the user prematurely.
|
||||
*/
|
||||
function dirtyValidator(validator: ValidatorFn) {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
return control.dirty ? validator(control) : null;
|
||||
};
|
||||
}
|
||||
|
||||
export function dirtyRequiredIf(predicate: (predicateCtrl: AbstractControl) => boolean) {
|
||||
return dirtyValidator(requiredIf(predicate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to dirtyValidator(Validator.required), however using dirtyValidator returns a new function
|
||||
* each time which prevents formControl.hasError from properly comparing functions for equality.
|
||||
*/
|
||||
export function dirtyRequired(control: AbstractControl): ValidationErrors | null {
|
||||
return control.dirty ? Validators.required(control) : null;
|
||||
}
|
||||
10
angular/src/validators/requiredIf.validator.ts
Normal file
10
angular/src/validators/requiredIf.validator.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { AbstractControl, ValidationErrors, Validators } from "@angular/forms";
|
||||
|
||||
/**
|
||||
* Returns a new validator which will apply Validators.required only if the predicate is true.
|
||||
*/
|
||||
export function requiredIf(predicate: (predicateCtrl: AbstractControl) => boolean) {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
return predicate(control) ? Validators.required(control) : null;
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user