mirror of
https://github.com/bitwarden/browser
synced 2026-02-09 13:10:17 +00:00
fix type & injection errors; add wrapper dialogRef for cdk base dialogRef
This commit is contained in:
@@ -607,5 +607,5 @@ export function openCollectionDialog(
|
||||
dialogService: DialogService,
|
||||
config: DialogConfig<CollectionDialogParams, DialogRef<CollectionDialogResult>>,
|
||||
) {
|
||||
return dialogService.open(CollectionDialogComponent, config);
|
||||
return dialogService.open<CollectionDialogResult>(CollectionDialogComponent, config);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import {
|
||||
Dialog as CdkDialog,
|
||||
DialogConfig,
|
||||
DialogRef as CdkDialogRef,
|
||||
DialogConfig as CdkDialogConfig,
|
||||
DialogRef as CdkDialogRefBase,
|
||||
DIALOG_DATA,
|
||||
DialogCloseOptions,
|
||||
} from "@angular/cdk/dialog";
|
||||
import { ComponentType, ScrollStrategy } from "@angular/cdk/overlay";
|
||||
import { ComponentPortal, Portal } from "@angular/cdk/portal";
|
||||
import { Injectable, InjectionToken, Injector, TemplateRef, inject } from "@angular/core";
|
||||
import { Injectable, Injector, TemplateRef, inject } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { NavigationEnd, Router } from "@angular/router";
|
||||
import { filter, firstValueFrom, map, Observable, Subject, switchMap } from "rxjs";
|
||||
@@ -42,13 +42,14 @@ class CustomBlockScrollStrategy implements ScrollStrategy {
|
||||
detach() {}
|
||||
}
|
||||
|
||||
export const IS_DRAWER_TOKEN = new InjectionToken<boolean>("IS_DRAWER");
|
||||
|
||||
export abstract class DialogRef<R = unknown, C = unknown>
|
||||
implements Pick<CdkDialogRef<R, C>, "close" | "closed" | "disableClose" | "componentInstance">
|
||||
{
|
||||
abstract readonly isDrawer?: boolean;
|
||||
|
||||
// --- From CdkDialogRef ---
|
||||
abstract close(result?: R, options?: DialogCloseOptions): void;
|
||||
abstract closed: Observable<R | undefined>;
|
||||
abstract readonly closed: Observable<R | undefined>;
|
||||
abstract disableClose: boolean | undefined;
|
||||
/**
|
||||
* @deprecated
|
||||
@@ -57,7 +58,14 @@ export abstract class DialogRef<R = unknown, C = unknown>
|
||||
abstract componentInstance: C | null;
|
||||
}
|
||||
|
||||
export type DialogConfig<D = unknown, R = unknown> = Pick<
|
||||
CdkDialogConfig<D, R>,
|
||||
"data" | "disableClose" | "ariaModal" | "positionStrategy" | "height" | "width"
|
||||
>;
|
||||
|
||||
class DrawerDialogRef<R = unknown, C = unknown> implements DialogRef<R, C> {
|
||||
readonly isDrawer = true;
|
||||
|
||||
private _closed = new Subject<R | undefined>();
|
||||
closed = this._closed.asObservable();
|
||||
disableClose = false;
|
||||
@@ -79,6 +87,38 @@ class DrawerDialogRef<R = unknown, C = unknown> implements DialogRef<R, C> {
|
||||
componentInstance: C | null = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* DialogRef that delegates functionality to the CDK implementation
|
||||
**/
|
||||
export class CdkDialogRef<R = unknown, C = unknown> implements DialogRef<R, C> {
|
||||
readonly isDrawer = false; // This is not a drawer dialog
|
||||
|
||||
/** This is not available until after construction, as it is returned by `Dialog.open`. */
|
||||
cdkDialogRef!: CdkDialogRefBase<R, C>;
|
||||
|
||||
// --- Delegated to CdkDialogRefBase ---
|
||||
|
||||
close(result?: R, options?: DialogCloseOptions): void {
|
||||
this.cdkDialogRef.close(result, options);
|
||||
}
|
||||
|
||||
get closed(): Observable<R | undefined> {
|
||||
return this.cdkDialogRef.closed;
|
||||
}
|
||||
|
||||
get disableClose(): boolean | undefined {
|
||||
return this.cdkDialogRef.disableClose;
|
||||
}
|
||||
set disableClose(value: boolean | undefined) {
|
||||
this.cdkDialogRef.disableClose = value;
|
||||
}
|
||||
|
||||
// Delegate the `componentInstance` property to the CDK DialogRef
|
||||
get componentInstance(): C | null {
|
||||
return this.cdkDialogRef.componentInstance;
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class DialogService {
|
||||
private dialog = inject(CdkDialog);
|
||||
@@ -107,17 +147,27 @@ export class DialogService {
|
||||
}
|
||||
}
|
||||
|
||||
open<R = unknown, D = unknown, C = any>(
|
||||
open<R = unknown, D = unknown, C = unknown>(
|
||||
componentOrTemplateRef: ComponentType<C> | TemplateRef<C>,
|
||||
config?: DialogConfig<D, CdkDialogRef<R, C>>,
|
||||
config?: DialogConfig<D, DialogRef<R, C>>,
|
||||
): DialogRef<R, C> {
|
||||
config = {
|
||||
// Create the injector with the custom DialogRef
|
||||
const ref = new CdkDialogRef<R, C>();
|
||||
const injector = this.createInjector({
|
||||
data: config?.data,
|
||||
dialogRef: ref,
|
||||
});
|
||||
|
||||
// Merge the custom config with the default config
|
||||
const _config = {
|
||||
backdropClass: this.backDropClasses,
|
||||
scrollStrategy: this.defaultScrollStrategy,
|
||||
injector,
|
||||
...config,
|
||||
};
|
||||
|
||||
return this.dialog.open(componentOrTemplateRef, config);
|
||||
ref.cdkDialogRef = this.dialog.open<R, D, C>(componentOrTemplateRef, _config);
|
||||
return ref;
|
||||
}
|
||||
|
||||
/** Opens a dialog in the side drawer */
|
||||
@@ -130,27 +180,7 @@ export class DialogService {
|
||||
const portal = new ComponentPortal(
|
||||
component,
|
||||
null,
|
||||
Injector.create({
|
||||
providers: [
|
||||
{
|
||||
provide: DIALOG_DATA,
|
||||
useValue: config?.data,
|
||||
},
|
||||
{
|
||||
provide: CdkDialogRef,
|
||||
useValue: this.activeDrawer,
|
||||
},
|
||||
{
|
||||
provide: DialogRef,
|
||||
useValue: this.activeDrawer,
|
||||
},
|
||||
{
|
||||
provide: IS_DRAWER_TOKEN,
|
||||
useValue: true,
|
||||
},
|
||||
],
|
||||
parent: this.injector,
|
||||
}),
|
||||
this.createInjector({ data: config?.data, dialogRef: this.activeDrawer }),
|
||||
);
|
||||
this.activeDrawer.portal = portal;
|
||||
this.drawerService.open(portal);
|
||||
@@ -189,4 +219,25 @@ export class DialogService {
|
||||
closeAll(): void {
|
||||
return this.dialog.closeAll();
|
||||
}
|
||||
|
||||
/** The injector that is passed to the opened dialog */
|
||||
private createInjector(opts: { data: unknown; dialogRef: DialogRef }): Injector {
|
||||
return Injector.create({
|
||||
providers: [
|
||||
{
|
||||
provide: DIALOG_DATA,
|
||||
useValue: opts.data,
|
||||
},
|
||||
{
|
||||
provide: DialogRef,
|
||||
useValue: opts.dialogRef,
|
||||
},
|
||||
{
|
||||
provide: CdkDialogRefBase,
|
||||
useValue: opts.dialogRef,
|
||||
},
|
||||
],
|
||||
parent: this.injector,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@let isDrawer = dialogRef.isDrawer;
|
||||
<section
|
||||
class="tw-flex tw-w-full tw-flex-col tw-self-center tw-overflow-hidden tw-border tw-border-solid tw-border-secondary-300 tw-bg-background tw-text-main"
|
||||
[ngClass]="[width, isDrawer ? 'tw-h-screen tw-border-t-0' : 'tw-rounded-xl']"
|
||||
|
||||
@@ -10,7 +10,7 @@ import { I18nPipe } from "@bitwarden/ui-common";
|
||||
import { BitIconButtonComponent } from "../../icon-button/icon-button.component";
|
||||
import { TypographyDirective } from "../../typography/typography.directive";
|
||||
import { fadeIn } from "../animations";
|
||||
import { DialogRef, IS_DRAWER_TOKEN } from "../dialog.service";
|
||||
import { DialogRef } from "../dialog.service";
|
||||
import { DialogCloseDirective } from "../directives/dialog-close.directive";
|
||||
import { DialogTitleContainerDirective } from "../directives/dialog-title-container.directive";
|
||||
|
||||
@@ -33,8 +33,7 @@ import { DialogTitleContainerDirective } from "../directives/dialog-title-contai
|
||||
],
|
||||
})
|
||||
export class DialogComponent {
|
||||
private dialogRef = inject(DialogRef, { optional: true });
|
||||
protected isDrawer = inject(IS_DRAWER_TOKEN, { optional: true }) ?? false;
|
||||
protected dialogRef = inject(DialogRef);
|
||||
|
||||
/** Background color */
|
||||
@Input()
|
||||
@@ -76,7 +75,9 @@ export class DialogComponent {
|
||||
return ["tw-flex", "tw-flex-col"]
|
||||
.concat(
|
||||
this.width,
|
||||
!this.isDrawer ? ["tw-p-4", "tw-w-screen", "tw-max-h-[90vh]"] : ["tw-min-h-screen"],
|
||||
!this.dialogRef.isDrawer
|
||||
? ["tw-p-4", "tw-w-screen", "tw-max-h-[90vh]"]
|
||||
: ["tw-min-h-screen"],
|
||||
)
|
||||
.flat();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user