2022-12-29 20:37:30 +01:00
|
|
|
import {
|
|
|
|
DEFAULT_DIALOG_CONFIG,
|
|
|
|
Dialog,
|
|
|
|
DialogConfig,
|
|
|
|
DialogRef,
|
|
|
|
DIALOG_SCROLL_STRATEGY,
|
|
|
|
} from "@angular/cdk/dialog";
|
|
|
|
import { ComponentType, Overlay, OverlayContainer } from "@angular/cdk/overlay";
|
|
|
|
import {
|
|
|
|
Inject,
|
|
|
|
Injectable,
|
|
|
|
Injector,
|
|
|
|
OnDestroy,
|
|
|
|
Optional,
|
|
|
|
SkipSelf,
|
|
|
|
TemplateRef,
|
|
|
|
} from "@angular/core";
|
|
|
|
import { NavigationEnd, Router } from "@angular/router";
|
2023-05-02 18:46:03 +02:00
|
|
|
import { filter, firstValueFrom, Subject, switchMap, takeUntil } from "rxjs";
|
2022-12-29 20:37:30 +01:00
|
|
|
|
2023-02-06 22:53:37 +01:00
|
|
|
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
|
|
|
|
import { AuthenticationStatus } from "@bitwarden/common/auth/enums/authentication-status";
|
2023-08-16 14:26:56 +02:00
|
|
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
2022-08-05 17:45:36 +02:00
|
|
|
|
2023-08-16 14:26:56 +02:00
|
|
|
import { SimpleConfigurableDialogComponent } from "./simple-dialog/simple-configurable-dialog/simple-configurable-dialog.component";
|
|
|
|
import { SimpleDialogOptions, Translation } from "./simple-dialog/types";
|
2023-01-24 22:38:14 +01:00
|
|
|
|
2022-08-05 17:45:36 +02:00
|
|
|
@Injectable()
|
2023-08-16 14:26:56 +02:00
|
|
|
export class DialogService extends Dialog implements OnDestroy {
|
2022-12-29 20:37:30 +01:00
|
|
|
private _destroy$ = new Subject<void>();
|
|
|
|
|
2023-05-02 18:46:03 +02:00
|
|
|
private backDropClasses = ["tw-fixed", "tw-bg-black", "tw-bg-opacity-30", "tw-inset-0"];
|
2022-12-29 20:37:30 +01:00
|
|
|
|
|
|
|
constructor(
|
|
|
|
/** Parent class constructor */
|
|
|
|
_overlay: Overlay,
|
|
|
|
_injector: Injector,
|
|
|
|
@Optional() @Inject(DEFAULT_DIALOG_CONFIG) _defaultOptions: DialogConfig,
|
|
|
|
@Optional() @SkipSelf() _parentDialog: Dialog,
|
|
|
|
_overlayContainer: OverlayContainer,
|
|
|
|
@Inject(DIALOG_SCROLL_STRATEGY) scrollStrategy: any,
|
|
|
|
|
|
|
|
/** Not in parent class */
|
|
|
|
@Optional() router: Router,
|
2023-08-16 14:26:56 +02:00
|
|
|
@Optional() authService: AuthService,
|
|
|
|
|
|
|
|
protected i18nService: I18nService,
|
2022-12-29 20:37:30 +01:00
|
|
|
) {
|
|
|
|
super(_overlay, _injector, _defaultOptions, _parentDialog, _overlayContainer, scrollStrategy);
|
|
|
|
|
|
|
|
/** Close all open dialogs if the vault locks */
|
|
|
|
if (router && authService) {
|
|
|
|
router.events
|
|
|
|
.pipe(
|
|
|
|
filter((event) => event instanceof NavigationEnd),
|
|
|
|
switchMap(() => authService.getAuthStatus()),
|
|
|
|
filter((v) => v !== AuthenticationStatus.Unlocked),
|
|
|
|
takeUntil(this._destroy$),
|
|
|
|
)
|
|
|
|
.subscribe(() => this.closeAll());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override ngOnDestroy(): void {
|
|
|
|
this._destroy$.next();
|
|
|
|
this._destroy$.complete();
|
|
|
|
super.ngOnDestroy();
|
|
|
|
}
|
2023-01-24 22:38:14 +01:00
|
|
|
|
|
|
|
override open<R = unknown, D = unknown, C = unknown>(
|
|
|
|
componentOrTemplateRef: ComponentType<C> | TemplateRef<C>,
|
|
|
|
config?: DialogConfig<D, DialogRef<R, C>>,
|
|
|
|
): DialogRef<R, C> {
|
|
|
|
config = {
|
|
|
|
backdropClass: this.backDropClasses,
|
|
|
|
...config,
|
|
|
|
};
|
|
|
|
|
|
|
|
return super.open(componentOrTemplateRef, config);
|
|
|
|
}
|
|
|
|
|
2023-05-02 18:46:03 +02:00
|
|
|
/**
|
|
|
|
* Opens a simple dialog, returns true if the user accepted the dialog.
|
|
|
|
*
|
|
|
|
* @param {SimpleDialogOptions} simpleDialogOptions - An object containing options for the dialog.
|
|
|
|
* @returns `boolean` - True if the user accepted the dialog, false otherwise.
|
|
|
|
*/
|
|
|
|
async openSimpleDialog(simpleDialogOptions: SimpleDialogOptions): Promise<boolean> {
|
2023-12-15 17:22:19 +01:00
|
|
|
const dialogRef = this.openSimpleDialogRef(simpleDialogOptions);
|
2023-05-02 18:46:03 +02:00
|
|
|
|
2023-08-16 14:26:56 +02:00
|
|
|
return firstValueFrom(dialogRef.closed);
|
2023-05-02 18:46:03 +02:00
|
|
|
}
|
|
|
|
|
2023-01-24 22:38:14 +01:00
|
|
|
/**
|
|
|
|
* Opens a simple dialog.
|
|
|
|
*
|
2023-12-15 17:22:19 +01:00
|
|
|
* You should probably use `openSimpleDialog` instead, unless you need to programmatically close the dialog.
|
2023-05-02 18:46:03 +02:00
|
|
|
*
|
2023-01-24 22:38:14 +01:00
|
|
|
* @param {SimpleDialogOptions} simpleDialogOptions - An object containing options for the dialog.
|
|
|
|
* @returns `DialogRef` - The reference to the opened dialog.
|
|
|
|
* Contains a closed observable which can be subscribed to for determining which button
|
2023-08-16 14:26:56 +02:00
|
|
|
* a user pressed
|
2023-01-24 22:38:14 +01:00
|
|
|
*/
|
2023-12-15 17:22:19 +01:00
|
|
|
openSimpleDialogRef(simpleDialogOptions: SimpleDialogOptions): DialogRef<boolean> {
|
|
|
|
return this.open<boolean, SimpleDialogOptions>(SimpleConfigurableDialogComponent, {
|
2023-01-24 22:38:14 +01:00
|
|
|
data: simpleDialogOptions,
|
|
|
|
disableClose: simpleDialogOptions.disableClose,
|
|
|
|
});
|
|
|
|
}
|
2023-08-16 14:26:56 +02:00
|
|
|
|
|
|
|
protected translate(translation: string | Translation, defaultKey?: string): string {
|
|
|
|
if (translation == null && defaultKey == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (translation == null) {
|
|
|
|
return this.i18nService.t(defaultKey);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Translation interface use implies we must localize.
|
|
|
|
if (typeof translation === "object") {
|
|
|
|
return this.i18nService.t(translation.key, ...(translation.placeholders ?? []));
|
|
|
|
}
|
|
|
|
|
|
|
|
return translation;
|
|
|
|
}
|
2022-08-05 17:45:36 +02:00
|
|
|
}
|