From 7406d5e02d751f22a0e3efb807d541d82ab48c29 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stephan=20M=C3=BCller?= Date: Tue, 30 Jul 2019 17:55:53 +0200 Subject: [PATCH] mgr/dashboard: Use onCancel on any modal event MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The problem was, that if 'onCancel' was provided, it wasn't used in all modal exit cases. Only for the close buttons (the X and the labeled one), but not if you clicked outside the modal or hit escape. 'onCancel' is currently only used inside the user management form, where the problem caused, that the submit button was not longer click able if the modal was hidden through clicking outside of it or hitting escape. Fixes: https://tracker.ceph.com/issues/40828 Signed-off-by: Stephan Müller --- .../confirmation-modal.component.spec.ts | 40 +++++++++++++++++++ .../confirmation-modal.component.ts | 22 +++++++--- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts index 21a82ca4f3c..67a1d434cc9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts @@ -58,6 +58,12 @@ class MockComponent { basicModal() { this.openModal(); } + + customCancelModal() { + this.openModal({ + onCancel: () => (this.returnValue = 'If you have todo something besides hiding the modal.') + }); + } } describe('ConfirmationModalComponent', () => { @@ -195,4 +201,38 @@ describe('ConfirmationModalComponent', () => { ); }); }); + + describe('custom cancel action', () => { + const expectCancelValue = () => + expectReturnValue('If you have todo something besides hiding the modal.'); + + beforeEach(() => { + mockComponent.customCancelModal(); + }); + + it('should use custom cancel action', () => { + fh.clickElement('.tc_backButton'); + expectCancelValue(); + }); + + it('should use custom cancel action if escape was pressed', () => { + hide('esc'); + expectCancelValue(); + }); + + it('should use custom cancel action if clicked outside the modal', () => { + hide('backdrop-click'); + expectCancelValue(); + }); + + it('should unsubscribe on destroy', () => { + hide('backdrop-click'); + expectCancelValue(); + const s = 'This value will not be changed.'; + mockComponent.returnValue = s; + component.ngOnDestroy(); + hide('backdrop-click'); + expectReturnValue(s); + }); + }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts index 617a7068603..79118925652 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts @@ -1,7 +1,8 @@ -import { Component, OnInit, TemplateRef } from '@angular/core'; +import { Component, OnDestroy, OnInit, TemplateRef } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; +import { Subscription } from 'rxjs'; @Component({ selector: 'cd-confirmation-modal', @@ -23,9 +24,16 @@ export class ConfirmationModalComponent implements OnInit, OnDestroy { // Component only boundCancel = this.cancel.bind(this); confirmationForm: FormGroup; + private onHide: Subscription; + private canceled = false; - constructor(public modalRef: BsModalRef) { + constructor(public modalRef: BsModalRef, private modalService: BsModalService) { this.confirmationForm = new FormGroup({}); + this.onHide = this.modalService.onHide.subscribe((e) => { + if (this.onCancel && (e || this.canceled)) { + this.onCancel(); + } + }); } ngOnInit() { @@ -42,11 +50,13 @@ export class ConfirmationModalComponent implements OnInit, OnDestroy { } } + ngOnDestroy() { + this.onHide.unsubscribe(); + } + cancel() { + this.canceled = true; this.modalRef.hide(); - if (this.onCancel) { - this.onCancel(); - } } stopLoadingSpinner() { -- 2.39.5