diff --git a/src/framework/theme/components/dialog/dialog-config.ts b/src/framework/theme/components/dialog/dialog-config.ts index dfa6f04f9e..8403399073 100644 --- a/src/framework/theme/components/dialog/dialog-config.ts +++ b/src/framework/theme/components/dialog/dialog-config.ts @@ -6,7 +6,6 @@ import { InjectionToken, ViewContainerRef } from '@angular/core'; - export const NB_DIALOG_CONFIG = new InjectionToken('Default dialog options'); /** @@ -56,6 +55,9 @@ export class NbDialogConfig { */ viewContainerRef: ViewContainerRef; + /** Closes dialog automatically on navigation events such as browser back button pressed */ + closeOnNavigation: boolean = true; + context: D; constructor(config: Partial) { diff --git a/src/framework/theme/components/dialog/dialog.service.ts b/src/framework/theme/components/dialog/dialog.service.ts index fbee7be8fa..d0dcf351a6 100644 --- a/src/framework/theme/components/dialog/dialog.service.ts +++ b/src/framework/theme/components/dialog/dialog.service.ts @@ -5,6 +5,7 @@ */ import { ComponentFactoryResolver, Inject, Injectable, Injector, TemplateRef, Type } from '@angular/core'; +import { Router, NavigationStart } from '@angular/router'; import { fromEvent as observableFromEvent } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; @@ -22,7 +23,6 @@ import { NB_DIALOG_CONFIG, NbDialogConfig } from './dialog-config'; import { NbDialogRef } from './dialog-ref'; import { NbDialogContainerComponent } from './dialog-container'; - /** * The `NbDialogService` helps to open dialogs. * @@ -138,19 +138,23 @@ import { NbDialogContainerComponent } from './dialog-container'; * */ @Injectable() export class NbDialogService { - constructor(@Inject(NB_DOCUMENT) protected document, - @Inject(NB_DIALOG_CONFIG) protected globalConfig, - protected positionBuilder: NbPositionBuilderService, - protected overlay: NbOverlayService, - protected injector: Injector, - protected cfr: ComponentFactoryResolver) { - } + constructor( + @Inject(NB_DOCUMENT) protected document, + @Inject(NB_DIALOG_CONFIG) protected globalConfig, + protected positionBuilder: NbPositionBuilderService, + protected overlay: NbOverlayService, + protected injector: Injector, + protected cfr: ComponentFactoryResolver, + protected router: Router, + ) {} /** * Opens new instance of the dialog, may receive optional config. * */ - open(content: Type | TemplateRef, - userConfig: Partial | string>> = {}): NbDialogRef { + open( + content: Type | TemplateRef, + userConfig: Partial | string>> = {}, + ): NbDialogRef { const config = new NbDialogConfig({ ...this.globalConfig, ...userConfig }); const overlayRef = this.createOverlay(config); const dialogRef = new NbDialogRef(overlayRef); @@ -159,6 +163,13 @@ export class NbDialogService { this.registerCloseListeners(config, overlayRef, dialogRef); + if (userConfig?.closeOnNavigation !== false) { + const subscription = this.router.events + .pipe(filter((event) => event instanceof NavigationStart)) + .subscribe(() => dialogRef.close()); + + dialogRef.onClose.subscribe(() => subscription.unsubscribe()); + } return dialogRef; } @@ -176,10 +187,7 @@ export class NbDialogService { } protected createPositionStrategy(): NbGlobalPositionStrategy { - return this.positionBuilder - .global() - .centerVertically() - .centerHorizontally(); + return this.positionBuilder.global().centerVertically().centerHorizontally(); } protected createScrollStrategy(hasScroll: boolean): NbScrollStrategy { @@ -197,10 +205,12 @@ export class NbDialogService { return containerRef.instance; } - protected createContent(config: NbDialogConfig, - content: Type | TemplateRef, - container: NbDialogContainerComponent, - dialogRef: NbDialogRef) { + protected createContent( + config: NbDialogConfig, + content: Type | TemplateRef, + container: NbDialogContainerComponent, + dialogRef: NbDialogRef, + ) { if (content instanceof TemplateRef) { const portal = this.createTemplatePortal(config, content, dialogRef); container.attachTemplatePortal(portal); @@ -209,14 +219,16 @@ export class NbDialogService { dialogRef.componentRef = container.attachComponentPortal(portal); if (config.context) { - Object.assign(dialogRef.componentRef.instance, { ...config.context }) + Object.assign(dialogRef.componentRef.instance, { ...config.context }); } } } - protected createTemplatePortal(config: NbDialogConfig, - content: TemplateRef, - dialogRef: NbDialogRef): NbTemplatePortal { + protected createTemplatePortal( + config: NbDialogConfig, + content: TemplateRef, + dialogRef: NbDialogRef, + ): NbTemplatePortal { return new NbTemplatePortal(content, null, { $implicit: config.context, dialogRef }); } @@ -224,16 +236,18 @@ export class NbDialogService { * We're creating portal with custom injector provided through config or using global injector. * This approach provides us capability inject `NbDialogRef` in dialog component. * */ - protected createComponentPortal(config: NbDialogConfig, - content: Type, - dialogRef: NbDialogRef): NbComponentPortal { + protected createComponentPortal( + config: NbDialogConfig, + content: Type, + dialogRef: NbDialogRef, + ): NbComponentPortal { const injector = this.createInjector(config); const portalInjector = new NbPortalInjector(injector, new WeakMap([[NbDialogRef, dialogRef]])); return new NbComponentPortal(content, config.viewContainerRef, portalInjector); } protected createInjector(config: NbDialogConfig): Injector { - return config.viewContainerRef && config.viewContainerRef.injector || this.injector; + return (config.viewContainerRef && config.viewContainerRef.injector) || this.injector; } protected registerCloseListeners(config: NbDialogConfig, overlayRef: NbOverlayRef, dialogRef: NbDialogRef) {