]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/eg2/src/app/share/dialog/dialog.component.ts
LP1807461 Admin page avoid errors on dialog dismissal
[Evergreen.git] / Open-ILS / src / eg2 / src / app / share / dialog / dialog.component.ts
1 import {Component, Input, OnInit, ViewChild, TemplateRef, EventEmitter} from '@angular/core';
2 import {NgbModal, NgbModalRef, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
3
4 /**
5  * Dialog base class.  Handles the ngbModal logic.
6  * Sub-classed component templates must have a #dialogContent selector
7  * at the root of the template (see ConfirmDialogComponent).
8  */
9
10 export interface DialogRejectionResponse {
11     // Did the user simply close the dialog without performing an action.
12     dismissed?: boolean;
13     // Relays error, etc. messages from the dialog handler to the caller.
14     message?: string;
15 }
16
17 @Component({
18     selector: 'eg-dialog',
19     template: '<ng-template></ng-template>'
20 })
21 export class DialogComponent implements OnInit {
22
23     // Assume all dialogs support a title attribute.
24     @Input() public dialogTitle: string;
25
26     // Pointer to the dialog content template.
27     @ViewChild('dialogContent')
28     private dialogContent: TemplateRef<any>;
29
30     // Emitted after open() is called on the ngbModal.
31     // Note when overriding open(), this will not fire unless also
32     // called in the overridding method.
33     onOpen$ = new EventEmitter<any>();
34
35     // The modalRef allows direct control of the modal instance.
36     private modalRef: NgbModalRef = null;
37
38     constructor(private modalService: NgbModal) {}
39
40     ngOnInit() {
41         this.onOpen$ = new EventEmitter<any>();
42     }
43
44     open(options?: NgbModalOptions): Promise<any> {
45
46         if (this.modalRef !== null) {
47             console.warn('Dismissing existing dialog');
48             this.dismiss();
49         }
50
51         this.modalRef = this.modalService.open(this.dialogContent, options);
52
53         if (this.onOpen$) {
54             // Let the digest cycle complete
55             setTimeout(() => this.onOpen$.emit(true));
56         }
57
58         return new Promise( (resolve, reject) => {
59
60             this.modalRef.result.then(
61                 (result) => {
62                     resolve(result);
63                     this.modalRef = null;
64                 },
65
66                 (result) => {
67                     // NgbModal creates some result values for us, which
68                     // are outside of our control.  Other dismissal
69                     // reasons are agreed upon by implementing subclasses.
70                     console.debug('dialog closed with ' + result);
71
72                     const dismissed = (
73                            result === 0 // body click
74                         || result === 1 // Esc key
75                         || result === 'canceled' // Cancel button
76                         || result === 'cross_click' // modal top-right X
77                     );
78
79                     const rejection: DialogRejectionResponse = {
80                         dismissed: dismissed,
81                         message: result
82                     };
83
84                     reject(rejection);
85                     this.modalRef = null;
86                 }
87             );
88         });
89     }
90
91     close(reason?: any): void {
92         if (this.modalRef) {
93             this.modalRef.close(reason);
94         }
95     }
96
97     dismiss(reason?: any): void {
98         if (this.modalRef) {
99             this.modalRef.dismiss(reason);
100         }
101     }
102 }
103
104