]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Use onCancel on any modal event
authorStephan Müller <smueller@suse.com>
Tue, 30 Jul 2019 15:55:53 +0000 (17:55 +0200)
committerStephan Müller <smueller@suse.com>
Wed, 4 Sep 2019 14:22:33 +0000 (16:22 +0200)
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 <smueller@suse.com>
src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts

index 21a82ca4f3c3889233c3b6bc7bc3d674b727f66e..67a1d434cc9e31dd1dd633b954581ecd290a0c7a 100644 (file)
@@ -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);
+    });
+  });
 });
index 617a7068603ec556a9bca66d48e59782a93b9daf..791189256526a8472e4430553008686935b695b2 100644 (file)
@@ -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() {