1
0
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:
Thomas Rittson
2022-03-02 07:31:00 +10:00
committed by GitHub
parent d919346517
commit d81eb7ddae
9 changed files with 274 additions and 34 deletions

View 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();
}
}

View 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, "");
}
}

View File

@@ -0,0 +1,5 @@
export interface SelectOptions {
name: string;
value: any;
disabled?: boolean;
}

View 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;
}

View 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;
};
}