Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(modal): remove key/mouse handlers only when modal is destroyed (#…
…3532) At the moment key/mouse handlers are removed when modal triggers dismiss event. The problem is that modal closure could be cancelled with `beforeDismiss` and modal will stay opened, but handlers will be removed. This commit introduces `closed$` event triggered inside `onDestroy` to clean up handlers. Fixes #3515
- Loading branch information
1 parent
fb8bb11
commit 01d508a
Showing
7 changed files
with
146 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
e2e-app/src/app/modal/stack-confirmation/modal-stack-confirmation.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<h3>Modal closure confirmation test</h3> | ||
|
||
<ng-template #modal let-modal> | ||
<div class="modal-header"> | ||
<h4 class="modal-title">Modal with closure confirmation</h4> | ||
<button id="close" type="button" class="close" aria-label="Close" (click)="modal.dismiss()"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
<div class="modal-body"> | ||
<p>This modal will trigger confirmation</p> | ||
</div> | ||
</ng-template> | ||
|
||
<ng-template #confirmation let-modal> | ||
<div class="modal-header"> | ||
<h4 class="modal-title">Are you sure you want to close the modal?</h4> | ||
<button id="dismiss" type="button" class="close" aria-label="Close" (click)="modal.dismiss()"> | ||
<span aria-hidden="true">×</span> | ||
</button> | ||
</div> | ||
<div class="modal-body"> | ||
<button id="confirm" class="btn btn-primary" (click)="modal.close()">Yep</button> | ||
</div> | ||
</ng-template> | ||
|
||
<button class="btn btn-outline-secondary ml-2" type="button" id="open-modal" (click)="openModal(modal)">Open Modal</button> |
13 changes: 13 additions & 0 deletions
13
e2e-app/src/app/modal/stack-confirmation/modal-stack-confirmation.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import {Component, TemplateRef, ViewChild} from '@angular/core'; | ||
import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; | ||
|
||
@Component({templateUrl: './modal-stack-confirmation.component.html'}) | ||
export class ModalStackConfirmationComponent { | ||
@ViewChild('confirmation', {static: true, read: TemplateRef}) confirmationTpl: TemplateRef<any>; | ||
|
||
constructor(private modalService: NgbModal) {} | ||
|
||
openModal(content: TemplateRef<any>) { | ||
this.modalService.open(content, {beforeDismiss: () => this.modalService.open(this.confirmationTpl).result}); | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
e2e-app/src/app/modal/stack-confirmation/modal-stack-confirmation.e2e-spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import {expectNoOpenModals, openUrl, sendKey} from '../../tools.po'; | ||
import {ModalStackConfirmationPage} from './modal-stack-confirmation.po'; | ||
import {Key} from 'protractor'; | ||
|
||
describe('Modal stacked with confirmation', () => { | ||
let page: ModalStackConfirmationPage; | ||
|
||
beforeAll(() => { page = new ModalStackConfirmationPage(); }); | ||
|
||
beforeEach(async() => await openUrl('modal/stack-confirmation')); | ||
|
||
afterEach(async() => { await expectNoOpenModals(); }); | ||
|
||
it('should close modals correctly using close button', async() => { | ||
await page.openModal(); | ||
|
||
// close with button | ||
await page.getModalClose().click(); | ||
expect(await page.getOpenModals().count()).toBe(2, 'Confirmation modal should be opened'); | ||
|
||
// cancel closure with button | ||
await page.getDismissalButton().click(); | ||
expect(await page.getOpenModals().count()).toBe(1, 'Confirmation modal should be dismissed'); | ||
|
||
// close again | ||
await page.getModalClose().click(); | ||
expect(await page.getOpenModals().count()).toBe(2, 'Confirmation modal should be re-opened'); | ||
|
||
// close all modals | ||
await page.getConfirmationButton().click(); | ||
}); | ||
|
||
it('should close modals correctly using ESC', async() => { | ||
await page.openModal(); | ||
|
||
// close with Escape | ||
await sendKey(Key.ESCAPE); | ||
expect(await page.getOpenModals().count()).toBe(2, 'Confirmation modal should be opened'); | ||
|
||
// cancel closure with Escape | ||
await sendKey(Key.ESCAPE); | ||
expect(await page.getOpenModals().count()).toBe(1, 'Confirmation modal should be dismissed'); | ||
|
||
// close again | ||
await sendKey(Key.ESCAPE); | ||
expect(await page.getOpenModals().count()).toBe(2, 'Confirmation modal should be re-opened'); | ||
|
||
// close all modals | ||
await page.getConfirmationButton().click(); | ||
}); | ||
|
||
it('should close modals correctly using backdrop click', async() => { | ||
await page.openModal(); | ||
|
||
// close with click | ||
await page.getModal(0).click(); | ||
expect(await page.getOpenModals().count()).toBe(2, 'Confirmation modal should be opened'); | ||
|
||
// cancel closure with click | ||
await page.getModal(1).click(); | ||
expect(await page.getOpenModals().count()).toBe(1, 'Confirmation modal should be dismissed'); | ||
|
||
// close again | ||
await page.getModal(0).click(); | ||
expect(await page.getOpenModals().count()).toBe(2, 'Confirmation modal should be re-opened'); | ||
|
||
// close all modals | ||
await page.getConfirmationButton().click(); | ||
}); | ||
|
||
}); |
22 changes: 22 additions & 0 deletions
22
e2e-app/src/app/modal/stack-confirmation/modal-stack-confirmation.po.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import {$, $$} from 'protractor'; | ||
|
||
export class ModalStackConfirmationPage { | ||
getOpenModals() { return $$('ngb-modal-window'); } | ||
|
||
getModal(index) { return this.getOpenModals().get(index); } | ||
|
||
getModalButton() { return $('#open-modal'); } | ||
|
||
getModalClose() { return $('#close'); } | ||
|
||
getConfirmationButton() { return $('#confirm'); } | ||
|
||
getDismissalButton() { return $('#dismiss'); } | ||
|
||
async openModal() { | ||
await this.getModalButton().click(); | ||
const modal = this.getModal(0); | ||
expect(await modal.isPresent()).toBeTruthy(`A modal should have been opened`); | ||
return modal; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters