LP1849372 Close all open dialogs on Angular route change
authorBill Erickson <berickxx@gmail.com>
Tue, 22 Oct 2019 19:54:13 +0000 (15:54 -0400)
committerMike Rylander <mrylander@gmail.com>
Wed, 23 Oct 2019 13:07:11 +0000 (09:07 -0400)
On all angular route changes, force close any open dialogs, since it
makes little sense for them to persist across interfaces.

To test:

[1] Navigate to Server Administration
[2] Navigate to Age Hold Protection Rule Configuration
[3] Double-click a grid row to open an edit dialog
[4] Click browser back button to return to the Server Admin page
[5] Confirm edit dialog closes once the navigation is complete.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Open-ILS/src/eg2/src/app/app.component.ts
Open-ILS/src/eg2/src/app/share/dialog/dialog.component.ts

index 3f95092..c70938f 100644 (file)
@@ -1,4 +1,6 @@
 import {Component} from '@angular/core';
+import {Router, NavigationEnd} from '@angular/router';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
 
 @Component({
   selector: 'eg-root',
@@ -6,6 +8,16 @@ import {Component} from '@angular/core';
 })
 
 export class BaseComponent {
+
+    constructor(private router: Router) {
+        this.router.events.subscribe(routeEvent => {
+            if (routeEvent instanceof NavigationEnd) {
+                // Prevent dialogs from persisting across navigation.
+                DialogComponent.closeAll();
+            }
+        });
+    }
+
 }
 
 
index 1532a1f..cafbbcf 100644 (file)
@@ -33,6 +33,13 @@ import {NgbModal, NgbModalRef, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap
 })
 export class DialogComponent implements OnInit {
 
+    // Track instances so we can refer to them later in closeAll()
+    // NOTE this could also be done by importing router and subscribing
+    // to route events here, but that would require all subclassed
+    // components to import and pass the router via the constructor.
+    static counter = 0;
+    static instances: {[ident: number]: any} = {};
+
     // Assume all dialogs support a title attribute.
     @Input() public dialogTitle: string;
 
@@ -40,6 +47,8 @@ export class DialogComponent implements OnInit {
     @ViewChild('dialogContent', {static: false})
     private dialogContent: TemplateRef<any>;
 
+    identifier: number = DialogComponent.counter++;
+
     // Emitted after open() is called on the ngbModal.
     // Note when overriding open(), this will not fire unless also
     // called in the overridding method.
@@ -53,6 +62,16 @@ export class DialogComponent implements OnInit {
 
     constructor(private modalService: NgbModal) {}
 
+    // Close all active dialogs
+    static closeAll() {
+        Object.keys(DialogComponent.instances).forEach(id => {
+            if (DialogComponent.instances[id]) {
+                DialogComponent.instances[id].close();
+                delete DialogComponent.instances[id];
+            }
+        });
+    }
+
     ngOnInit() {
         this.onOpen$ = new EventEmitter<any>();
     }
@@ -65,6 +84,7 @@ export class DialogComponent implements OnInit {
         }
 
         this.modalRef = this.modalService.open(this.dialogContent, options);
+        DialogComponent.instances[this.identifier] = this;
 
         if (this.onOpen$) {
             // Let the digest cycle complete
@@ -127,7 +147,9 @@ export class DialogComponent implements OnInit {
             this.observer = null;
         }
         this.modalRef = null;
+        delete DialogComponent.instances[this.identifier];
     }
+
 }