mirror of
https://github.com/bitwarden/directory-connector
synced 2025-12-13 14:53:16 +00:00
Copy jslib into Directory Connector [TI-6] (#262)
This commit is contained in:
23
jslib/angular/src/directives/a11y-title.directive.ts
Normal file
23
jslib/angular/src/directives/a11y-title.directive.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Directive, ElementRef, Input, Renderer2 } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "[appA11yTitle]",
|
||||
})
|
||||
export class A11yTitleDirective {
|
||||
@Input() set appA11yTitle(title: string) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
private title: string;
|
||||
|
||||
constructor(private el: ElementRef, private renderer: Renderer2) {}
|
||||
|
||||
ngOnInit() {
|
||||
if (!this.el.nativeElement.hasAttribute("title")) {
|
||||
this.renderer.setAttribute(this.el.nativeElement, "title", this.title);
|
||||
}
|
||||
if (!this.el.nativeElement.hasAttribute("aria-label")) {
|
||||
this.renderer.setAttribute(this.el.nativeElement, "aria-label", this.title);
|
||||
}
|
||||
}
|
||||
}
|
||||
49
jslib/angular/src/directives/api-action.directive.ts
Normal file
49
jslib/angular/src/directives/api-action.directive.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Directive, ElementRef, Input, OnChanges } from "@angular/core";
|
||||
|
||||
import { LogService } from "jslib-common/abstractions/log.service";
|
||||
import { ErrorResponse } from "jslib-common/models/response/errorResponse";
|
||||
|
||||
import { ValidationService } from "../services/validation.service";
|
||||
|
||||
/**
|
||||
* Provides error handling, in particular for any error returned by the server in an api call.
|
||||
* Attach it to a <form> element and provide the name of the class property that will hold the api call promise.
|
||||
* e.g. <form [appApiAction]="this.formPromise">
|
||||
* Any errors/rejections that occur will be intercepted and displayed as error toasts.
|
||||
*/
|
||||
@Directive({
|
||||
selector: "[appApiAction]",
|
||||
})
|
||||
export class ApiActionDirective implements OnChanges {
|
||||
@Input() appApiAction: Promise<any>;
|
||||
|
||||
constructor(
|
||||
private el: ElementRef,
|
||||
private validationService: ValidationService,
|
||||
private logService: LogService
|
||||
) {}
|
||||
|
||||
ngOnChanges(changes: any) {
|
||||
if (this.appApiAction == null || this.appApiAction.then == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.el.nativeElement.loading = true;
|
||||
|
||||
this.appApiAction.then(
|
||||
(response: any) => {
|
||||
this.el.nativeElement.loading = false;
|
||||
},
|
||||
(e: any) => {
|
||||
this.el.nativeElement.loading = false;
|
||||
|
||||
if ((e as ErrorResponse).captchaRequired) {
|
||||
this.logService.error("Captcha required error response: " + e.getSingleMessage());
|
||||
return;
|
||||
}
|
||||
this.logService?.error(`Received API exception: ${e}`);
|
||||
this.validationService.showError(e);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
27
jslib/angular/src/directives/autofocus.directive.ts
Normal file
27
jslib/angular/src/directives/autofocus.directive.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Directive, ElementRef, Input, NgZone } from "@angular/core";
|
||||
import { take } from "rxjs/operators";
|
||||
|
||||
import { Utils } from "jslib-common/misc/utils";
|
||||
|
||||
@Directive({
|
||||
selector: "[appAutofocus]",
|
||||
})
|
||||
export class AutofocusDirective {
|
||||
@Input() set appAutofocus(condition: boolean | string) {
|
||||
this.autofocus = condition === "" || condition === true;
|
||||
}
|
||||
|
||||
private autofocus: boolean;
|
||||
|
||||
constructor(private el: ElementRef, private ngZone: NgZone) {}
|
||||
|
||||
ngOnInit() {
|
||||
if (!Utils.isMobileBrowser && this.autofocus) {
|
||||
if (this.ngZone.isStable) {
|
||||
this.el.nativeElement.focus();
|
||||
} else {
|
||||
this.ngZone.onStable.pipe(take(1)).subscribe(() => this.el.nativeElement.focus());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
12
jslib/angular/src/directives/blur-click.directive.ts
Normal file
12
jslib/angular/src/directives/blur-click.directive.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Directive, ElementRef, HostListener } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "[appBlurClick]",
|
||||
})
|
||||
export class BlurClickDirective {
|
||||
constructor(private el: ElementRef) {}
|
||||
|
||||
@HostListener("click") onClick() {
|
||||
this.el.nativeElement.blur();
|
||||
}
|
||||
}
|
||||
59
jslib/angular/src/directives/box-row.directive.ts
Normal file
59
jslib/angular/src/directives/box-row.directive.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Directive, ElementRef, HostListener, OnInit } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "[appBoxRow]",
|
||||
})
|
||||
export class BoxRowDirective implements OnInit {
|
||||
el: HTMLElement = null;
|
||||
formEls: Element[];
|
||||
|
||||
constructor(elRef: ElementRef) {
|
||||
this.el = elRef.nativeElement;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.formEls = Array.from(
|
||||
this.el.querySelectorAll('input:not([type="hidden"]), select, textarea')
|
||||
);
|
||||
this.formEls.forEach((formEl) => {
|
||||
formEl.addEventListener(
|
||||
"focus",
|
||||
() => {
|
||||
this.el.classList.add("active");
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
formEl.addEventListener(
|
||||
"blur",
|
||||
() => {
|
||||
this.el.classList.remove("active");
|
||||
},
|
||||
false
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener("click", ["$event"]) onClick(event: Event) {
|
||||
const target = event.target as HTMLElement;
|
||||
if (
|
||||
target !== this.el &&
|
||||
!target.classList.contains("progress") &&
|
||||
!target.classList.contains("progress-bar")
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.formEls.length > 0) {
|
||||
const formEl = this.formEls[0] as HTMLElement;
|
||||
if (formEl.tagName.toLowerCase() === "input") {
|
||||
const inputEl = formEl as HTMLInputElement;
|
||||
if (inputEl.type != null && inputEl.type.toLowerCase() === "checkbox") {
|
||||
inputEl.click();
|
||||
return;
|
||||
}
|
||||
}
|
||||
formEl.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
14
jslib/angular/src/directives/fallback-src.directive.ts
Normal file
14
jslib/angular/src/directives/fallback-src.directive.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { Directive, ElementRef, HostListener, Input } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "[appFallbackSrc]",
|
||||
})
|
||||
export class FallbackSrcDirective {
|
||||
@Input("appFallbackSrc") appFallbackSrc: string;
|
||||
|
||||
constructor(private el: ElementRef) {}
|
||||
|
||||
@HostListener("error") onError() {
|
||||
this.el.nativeElement.src = this.appFallbackSrc;
|
||||
}
|
||||
}
|
||||
10
jslib/angular/src/directives/stop-click.directive.ts
Normal file
10
jslib/angular/src/directives/stop-click.directive.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Directive, HostListener } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "[appStopClick]",
|
||||
})
|
||||
export class StopClickDirective {
|
||||
@HostListener("click", ["$event"]) onClick($event: MouseEvent) {
|
||||
$event.preventDefault();
|
||||
}
|
||||
}
|
||||
10
jslib/angular/src/directives/stop-prop.directive.ts
Normal file
10
jslib/angular/src/directives/stop-prop.directive.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Directive, HostListener } from "@angular/core";
|
||||
|
||||
@Directive({
|
||||
selector: "[appStopProp]",
|
||||
})
|
||||
export class StopPropDirective {
|
||||
@HostListener("click", ["$event"]) onClick($event: MouseEvent) {
|
||||
$event.stopPropagation();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user