]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Use ng-bootstrap for Modal 35370/head
authorTiago Melo <tmelo@suse.com>
Fri, 29 May 2020 14:33:19 +0000 (14:33 +0000)
committerTiago Melo <tmelo@suse.com>
Thu, 25 Jun 2020 13:03:03 +0000 (13:03 +0000)
Fixes: https://tracker.ceph.com/issues/45759
Signed-off-by: Tiago Melo <tmelo@suse.com>
152 files changed:
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-list/pool-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-form/rbd-namespace-form-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-namespace-list/rbd-namespace-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-form/rbd-snapshot-form-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-snapshot-list/rbd-snapshot-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-list/rbd-trash-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-move-modal/rbd-trash-move-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-purge-modal/rbd-trash-purge-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-trash-restore-modal/rbd-trash-restore-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-clients/cephfs-clients.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-directories/cephfs-directories.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/inventory/inventory-devices/inventory-devices.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-creation-preview-modal/osd-creation-preview-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-groups/osd-devices-selection-groups.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts
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
src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss
src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-modal/orchestrator-doc-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-modal/orchestrator-doc-modal.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-modal/orchestrator-doc-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/dep-checker.service.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/dep-checker.service.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/testing/unit-test-helper.ts

index 702af5d37cf02794032bb5606433aec8d408322e..1a3800c90f69ee343bb331c4ba930fd3c944552d 100644 (file)
@@ -7,7 +7,6 @@ import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
 import { TreeModule } from 'angular-tree-component';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
 import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
-import { ModalModule } from 'ngx-bootstrap/modal';
 
 import { ActionLabels, URLVerbs } from '../../shared/constants/app.constants';
 import { FeatureTogglesGuardService } from '../../shared/services/feature-toggles-guard.service';
@@ -48,7 +47,6 @@ import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal/rbd-tra
     NgbNavModule,
     BsDatepickerModule.forRoot(),
     NgbTooltipModule,
-    ModalModule.forRoot(),
     SharedModule,
     RouterModule,
     NgBootstrapFormValidationModule,
index 605f1682928e2f00bca3175a48a3ad7a6a0aa9ca..ff05fa160868b81c4e6a4c7cf44e1078b5a65d66 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Discovery Authentication</ng-container>
 
                           [form]="discoveryForm"
                           *ngIf="hasPermission"
                           i18n>Submit</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 6d867cad0e096b60131a1eb35ffc0d8f57d1a25c..ed0a6652187cc4ef842d360418c6a0fcce91c2fb 100644 (file)
@@ -8,7 +8,7 @@ import { ReactiveFormsModule } from '@angular/forms';
 import { By } from '@angular/platform-browser';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import {
@@ -39,7 +39,7 @@ describe('IscsiTargetDiscoveryModalComponent', () => {
       ToastrModule.forRoot(),
       RouterTestingModule
     ],
-    providers: [i18nProviders, BsModalRef]
+    providers: [i18nProviders, NgbActiveModal]
   });
 
   beforeEach(() => {
index fcf9e27c142cbc9016603beb1fd0583542436e19..9f150747d756001fe50fea8a4510852eef9bdee8 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { IscsiService } from '../../../shared/api/iscsi.service';
 import { NotificationType } from '../../../shared/enum/notification-type.enum';
@@ -27,7 +27,7 @@ export class IscsiTargetDiscoveryModalComponent implements OnInit {
 
   constructor(
     private authStorageService: AuthStorageService,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private iscsiService: IscsiService,
     private notificationService: NotificationService,
     private i18n: I18n
@@ -113,7 +113,7 @@ export class IscsiTargetDiscoveryModalComponent implements OnInit {
           NotificationType.success,
           this.i18n('Updated discovery authentication')
         );
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
       () => {
         this.discoveryForm.setErrors({ cdSubmitButton: true });
index 68d24a4613abe4f6d7584486f75c5fe2f325a1ea..c5bead7dc38869e4b47f2ca624a9c823afdde9d1 100644 (file)
@@ -2,9 +2,9 @@ import { Component, OnInit } from '@angular/core';
 import { FormArray, FormControl, Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin } from 'rxjs';
 
 import { IscsiService } from '../../../shared/api/iscsi.service';
@@ -17,6 +17,7 @@ import { CdForm } from '../../../shared/forms/cd-form';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { CdValidators } from '../../../shared/forms/cd-validators';
 import { FinishedTask } from '../../../shared/models/finished-task';
+import { ModalService } from '../../../shared/services/modal.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { IscsiTargetImageSettingsModalComponent } from '../iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component';
 import { IscsiTargetIqnSettingsModalComponent } from '../iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component';
@@ -29,7 +30,7 @@ import { IscsiTargetIqnSettingsModalComponent } from '../iscsi-target-iqn-settin
 export class IscsiTargetFormComponent extends CdForm implements OnInit {
   cephIscsiConfigVersion: number;
   targetForm: CdFormGroup;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   api_version = 0;
   minimum_gateways = 1;
   target_default_controls: any;
@@ -90,7 +91,7 @@ export class IscsiTargetFormComponent extends CdForm implements OnInit {
 
   constructor(
     private iscsiService: IscsiService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private rbdService: RbdService,
     private router: Router,
     private route: ActivatedRoute,
@@ -785,7 +786,7 @@ export class IscsiTargetFormComponent extends CdForm implements OnInit {
       target_controls_limits: this.target_controls_limits
     };
 
-    this.modalRef = this.modalService.show(IscsiTargetIqnSettingsModalComponent, { initialState });
+    this.modalRef = this.modalService.show(IscsiTargetIqnSettingsModalComponent, initialState);
   }
 
   imageSettingsModal(image: string) {
@@ -799,9 +800,7 @@ export class IscsiTargetFormComponent extends CdForm implements OnInit {
       control: this.targetForm.get('disks')
     };
 
-    this.modalRef = this.modalService.show(IscsiTargetImageSettingsModalComponent, {
-      initialState
-    });
+    this.modalRef = this.modalService.show(IscsiTargetImageSettingsModalComponent, initialState);
   }
 
   validFeatures(image: Record<string, any>, backstore: string) {
index 8bd8d45975ed09430361d9afb33450b66f668a4e..21d8d00e213a52460c7a7933a3b690f5305c3025 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title">
     <ng-container i18n>Configure</ng-container>&nbsp;
     <small>{{ image }}</small>
@@ -86,7 +86,7 @@
         <cd-submit-button i18n
                           [form]="settingsForm"
                           (submitAction)="save()">Confirm</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 921292bcdb046a4e9f862b88b147b616e6684326..10ac2c762bddb3e3e035dc918f4484c65c95cb7d 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { FormControl, ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
@@ -17,7 +17,7 @@ describe('IscsiTargetImageSettingsModalComponent', () => {
   configureTestBed({
     declarations: [IscsiTargetImageSettingsModalComponent, IscsiSettingComponent],
     imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index f238d3b4c698cb5f474431d682777ac6f7b88911..36d2e70f0d579359045301ad2c8c04aff7fbebef 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 import { AbstractControl, FormControl } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { IscsiService } from '../../../shared/api/iscsi.service';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
@@ -23,7 +23,7 @@ export class IscsiTargetImageSettingsModalComponent implements OnInit {
 
   settingsForm: CdFormGroup;
 
-  constructor(public modalRef: BsModalRef, public iscsiService: IscsiService) {}
+  constructor(public activeModal: NgbActiveModal, public iscsiService: IscsiService) {}
 
   ngOnInit() {
     const fg: Record<string, FormControl> = {
@@ -77,6 +77,6 @@ export class IscsiTargetImageSettingsModalComponent implements OnInit {
     this.imagesSettings[this.image][backstore] = settings;
     this.imagesSettings = { ...this.imagesSettings };
     this.control.updateValueAndValidity({ emitEvent: false });
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 }
index 7eeacef4f55834cd435c81799b5cc0a2caa1790e..2df24f42c637aa397a6efff55f22407c1eac9c9e 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Advanced Settings</ng-container>
 
@@ -26,7 +26,7 @@
         <cd-submit-button i18n
                           [form]="settingsForm"
                           (submitAction)="save()">Confirm</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 521bcbf22d8070a3e3c1eb08df25f9fd301c4f83..ac6d883499eff41fdc0f00745c9bf047f79d6f64 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { FormControl, ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
@@ -17,7 +17,7 @@ describe('IscsiTargetIqnSettingsModalComponent', () => {
   configureTestBed({
     declarations: [IscsiTargetIqnSettingsModalComponent, IscsiSettingComponent],
     imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index 8e92f707ce07f1e7712e860eaed153920015db02..dcb7a754c409bc34d6f5040400bcb1ecea190577 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 import { FormControl } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { IscsiService } from '../../../shared/api/iscsi.service';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
@@ -19,7 +19,7 @@ export class IscsiTargetIqnSettingsModalComponent implements OnInit {
 
   settingsForm: CdFormGroup;
 
-  constructor(public modalRef: BsModalRef, public iscsiService: IscsiService) {}
+  constructor(public activeModal: NgbActiveModal, public iscsiService: IscsiService) {}
 
   ngOnInit() {
     const fg: Record<string, FormControl> = {};
@@ -39,7 +39,7 @@ export class IscsiTargetIqnSettingsModalComponent implements OnInit {
     });
 
     this.target_controls.setValue(settings);
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 
   getTargetControlLimits(setting: string) {
index 00f830978f31f9eb390851cb8ac563eaa962521b..91361703629df0b247a4a2e1ef2bf6e1e50fee1e 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { Subscription } from 'rxjs';
 
 import { IscsiService } from '../../../shared/api/iscsi.service';
@@ -21,6 +21,7 @@ import { Task } from '../../../shared/models/task';
 import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe';
 import { NotAvailablePipe } from '../../../shared/pipes/not-available.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { SummaryService } from '../../../shared/services/summary.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
@@ -39,7 +40,7 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit,
   available: boolean = undefined;
   columns: CdTableColumn[];
   docsUrl: string;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   permission: Permission;
   selection = new CdTableSelection();
   cephIscsiConfigVersion: number;
@@ -66,7 +67,7 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit,
     private cephReleaseNamePipe: CephReleaseNamePipe,
     private notAvailablePipe: NotAvailablePipe,
     private summaryservice: SummaryService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     public actionLabels: ActionLabelsI18n
   ) {
@@ -221,21 +222,19 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit,
     const target_iqn = this.selection.first().target_iqn;
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: this.i18n('iSCSI target'),
-        itemNames: [target_iqn],
-        submitActionObservable: () =>
-          this.taskWrapper.wrapTaskAroundCall({
-            task: new FinishedTask('iscsi/target/delete', {
-              target_iqn: target_iqn
-            }),
-            call: this.iscsiService.deleteTarget(target_iqn)
-          })
-      }
+      itemDescription: this.i18n('iSCSI target'),
+      itemNames: [target_iqn],
+      submitActionObservable: () =>
+        this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask('iscsi/target/delete', {
+            target_iqn: target_iqn
+          }),
+          call: this.iscsiService.deleteTarget(target_iqn)
+        })
     });
   }
 
   configureDiscoveryAuth() {
-    this.modalService.show(IscsiTargetDiscoveryModalComponent, {});
+    this.modalService.show(IscsiTargetDiscoveryModalComponent);
   }
 }
index 7c1c62b2d4da1bd9e87740f641d8ebc57d1c2d1c..3e2a1867ae3c334752e4b23d226d131312744d47 100755 (executable)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Create Bootstrap Token</ng-container>
 
@@ -82,7 +82,7 @@
       </div>
 
       <div class="modal-footer">
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Close"
                         i18n-name>
         </cd-back-button>
index cd27bf29081fec921348f502fe22b728f033f83b..0200547c407a3bb3fac705070f2921e3b227745e 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -33,7 +33,7 @@ describe('BootstrapCreateModalComponent', () => {
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -69,7 +69,7 @@ describe('BootstrapCreateModalComponent', () => {
   describe('generate token', () => {
     beforeEach(() => {
       spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
       fixture.detectChanges();
     });
 
index fb92f27fa704a017d05a43525a325a8e380472bf..16c52e7d36f5145e737b701492b038d59a9b2b5f 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnDestroy, OnInit } from '@angular/core';
 import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { concat, forkJoin, Subscription } from 'rxjs';
 import { last, tap } from 'rxjs/operators';
 
@@ -27,7 +27,7 @@ export class BootstrapCreateModalComponent implements OnDestroy, OnInit {
   createBootstrapForm: CdFormGroup;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
index a1998a12118429a1696026584a33306928755b50..9f901d98ec954898761ddc3fa450f69ad8d6f133 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Import Bootstrap Token</ng-container>
 
@@ -90,7 +90,7 @@
         <cd-submit-button i18n
                           [form]="importBootstrapForm"
                           (submitAction)="import()">Import</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Close"
                         i18n-name>
         </cd-back-button>
index e5a37603d324c8e242f4813144ffbe1bfb35bbdf..9acfabb0875185de7bffa9c90263265989fd8332 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -33,7 +33,7 @@ describe('BootstrapImportModalComponent', () => {
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -69,7 +69,7 @@ describe('BootstrapImportModalComponent', () => {
   describe('import token', () => {
     beforeEach(() => {
       spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
       fixture.detectChanges();
     });
 
index 0b7c9e0c90feca9ea5354b71d1f13f9954c8d70e..e534596d107a2da929a79be5b58c9dc7c8134f37 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnDestroy, OnInit } from '@angular/core';
 import { FormControl, FormGroup, ValidatorFn, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { concat, forkJoin, Observable, Subscription } from 'rxjs';
 import { last } from 'rxjs/operators';
 
@@ -32,7 +32,7 @@ export class BootstrapImportModalComponent implements OnInit, OnDestroy {
   ];
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
@@ -178,7 +178,7 @@ export class BootstrapImportModalComponent implements OnInit, OnDestroy {
       error: finishHandler,
       complete: () => {
         finishHandler();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
index 9aacaa43cb0910a5b4c8bb2c0728135406241f7f..09f97bfa54f7f81c743a82e061f074797b0d3eb1 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Edit site name</ng-container>
 
@@ -33,7 +33,7 @@
         <cd-submit-button i18n
                           [form]="editSiteNameForm"
                           (submitAction)="update()">Update</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 05b93a6ae87b12cd9839f66648b2e8e2db596969..fc66c8689512103a5c68ef4a97cb29dae99ed03b 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -28,7 +28,7 @@ describe('EditSiteNameModalComponent', () => {
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -50,14 +50,14 @@ describe('EditSiteNameModalComponent', () => {
     beforeEach(() => {
       spyOn(rbdMirroringService, 'getSiteName').and.callFake(() => of({ site_name: 'site-A' }));
       spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
       fixture.detectChanges();
     });
 
     afterEach(() => {
       expect(rbdMirroringService.getSiteName).toHaveBeenCalledTimes(1);
       expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('should call setSiteName', () => {
index c6ede8467422f008c63152e703394d8178325b65..7ddbbaad469a8a626ed6034cc55a3d14d509b235 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { FormControl } from '@angular/forms';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
 import { CdFormGroup } from '../../../../shared/forms/cd-form-group';
@@ -19,7 +19,7 @@ export class EditSiteNameModalComponent implements OnInit {
   editSiteNameForm: CdFormGroup;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
@@ -49,7 +49,7 @@ export class EditSiteNameModalComponent implements OnInit {
       error: () => this.editSiteNameForm.setErrors({ cdSubmitButton: true }),
       complete: () => {
         this.rbdMirroringService.refresh();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
index 1992f3965661b8072be6d3964d268ffc5b08369d..897c74c43b84d7b4141d6702565269ae9ffeeb17 100644 (file)
@@ -5,7 +5,6 @@ import { RouterModule } from '@angular/router';
 
 import { NgbNavModule, NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
-import { ModalModule } from 'ngx-bootstrap/modal';
 
 import { SharedModule } from '../../../shared/shared.module';
 import { BootstrapCreateModalComponent } from './bootstrap-create-modal/bootstrap-create-modal.component';
@@ -28,7 +27,6 @@ import { PoolListComponent } from './pool-list/pool-list.component';
     FormsModule,
     ReactiveFormsModule,
     NgbProgressbarModule,
-    ModalModule.forRoot(),
     NgBootstrapFormValidationModule
   ],
   declarations: [
index a73db2f62fafa7acb8fec31a5ff39297db849347..5220912c14759cc2864f2ea6d021fa04984748d9 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnDestroy, OnInit } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { Subscription } from 'rxjs';
 
 import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
@@ -11,6 +11,7 @@ import { CdTableAction } from '../../../../shared/models/cd-table-action';
 import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
 import { Permission } from '../../../../shared/models/permissions';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { Pool } from '../../../pool/pool';
 import { BootstrapCreateModalComponent } from '../bootstrap-create-modal/bootstrap-create-modal.component';
 import { BootstrapImportModalComponent } from '../bootstrap-import-modal/bootstrap-import-modal.component';
@@ -25,7 +26,7 @@ export class OverviewComponent implements OnInit, OnDestroy {
   permission: Permission;
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   peersExist = true;
   siteName: any;
   status: ViewCacheStatus;
@@ -34,7 +35,7 @@ export class OverviewComponent implements OnInit, OnDestroy {
   constructor(
     private authStorageService: AuthStorageService,
     private rbdMirroringService: RbdMirroringService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().rbdMirroring;
@@ -84,20 +85,20 @@ export class OverviewComponent implements OnInit, OnDestroy {
     const initialState = {
       siteName: this.siteName
     };
-    this.modalRef = this.modalService.show(EditSiteNameModalComponent, { initialState });
+    this.modalRef = this.modalService.show(EditSiteNameModalComponent, initialState);
   }
 
   createBootstrapModal() {
     const initialState = {
       siteName: this.siteName
     };
-    this.modalRef = this.modalService.show(BootstrapCreateModalComponent, { initialState });
+    this.modalRef = this.modalService.show(BootstrapCreateModalComponent, initialState);
   }
 
   importBootstrapModal() {
     const initialState = {
       siteName: this.siteName
     };
-    this.modalRef = this.modalService.show(BootstrapImportModalComponent, { initialState });
+    this.modalRef = this.modalService.show(BootstrapImportModalComponent, initialState);
   }
 }
index 1be453beed0bcafff0360017e927660c9a7f2af3..7facf5ba9b463c865196d1c477e01f8ab26670f8 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Edit pool mirror mode</ng-container>
 
@@ -37,7 +37,7 @@
         <cd-submit-button i18n
                           [form]="editModeForm"
                           (submitAction)="update()">Update</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 45e321d152fb75c12a51797dea8625f50d47e224..acafbca8473d400269f548f392bd3c75afb6ecb3 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -33,7 +33,7 @@ describe('PoolEditModeModalComponent', () => {
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -56,11 +56,11 @@ describe('PoolEditModeModalComponent', () => {
 
   describe('update pool mode', () => {
     beforeEach(() => {
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
     });
 
     afterEach(() => {
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('should call updatePool', () => {
index 13ab438f4fece25335aa3e9cf9184739fed65602..e706af9a7f5c57e7c9497203487300673163a404 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnDestroy, OnInit } from '@angular/core';
 import { AbstractControl, FormControl, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { Subscription } from 'rxjs';
 
 import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
@@ -37,7 +37,7 @@ export class PoolEditModeModalComponent implements OnInit, OnDestroy {
   ];
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
@@ -97,7 +97,7 @@ export class PoolEditModeModalComponent implements OnInit, OnDestroy {
       error: () => this.editModeForm.setErrors({ cdSubmitButton: true }),
       complete: () => {
         this.rbdMirroringService.refresh();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
index 4d70ad7e8a13cd891dcd09232f9b8f47db759c2e..942e7a66b8e4a54921aaeb861728f54d9004df46 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>{mode, select, edit {Edit} other {Add}}
   pool mirror peer</ng-container>
@@ -95,7 +95,7 @@
         <cd-submit-button i18n
                           [form]="editPeerForm"
                           (submitAction)="update()">Submit</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 7cd8e5fb3a8d29dbf25cf316686ca4bf7f1345c1..578e07e481c2e35f6c5f0491e08d5d0964b7fcd7 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -34,7 +34,7 @@ describe('PoolEditPeerModalComponent', () => {
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -60,13 +60,13 @@ describe('PoolEditPeerModalComponent', () => {
       component.mode = 'add';
       component.peerUUID = undefined;
       spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
       fixture.detectChanges();
     });
 
     afterEach(() => {
       expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('should call addPeer', () => {
@@ -103,14 +103,14 @@ describe('PoolEditPeerModalComponent', () => {
 
       spyOn(rbdMirroringService, 'getPeer').and.callFake(() => of(response));
       spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
       fixture.detectChanges();
     });
 
     afterEach(() => {
       expect(rbdMirroringService.getPeer).toHaveBeenCalledWith('somePool', 'somePeer');
       expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('should call updatePeer', () => {
index 4fd127cb346750bffd5dbbc8877333f558787c09..56a38656af75db25f3e99f6232626edeee9014f6 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { AbstractControl, FormControl, Validators } from '@angular/forms';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
 import { CdFormGroup } from '../../../../shared/forms/cd-form-group';
@@ -28,7 +28,7 @@ export class PoolEditPeerModalComponent implements OnInit {
   response: PoolEditPeerResponseModel;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
@@ -132,7 +132,7 @@ export class PoolEditPeerModalComponent implements OnInit {
       error: () => this.editPeerForm.setErrors({ cdSubmitButton: true }),
       complete: () => {
         this.rbdMirroringService.refresh();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
index 7009a8a41fdfe739ed2f18a04f2239e09a4441a6..10136692c51d9c1a8fd74ad699f9197a2beef3f3 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { Observable, Subscriber, Subscription } from 'rxjs';
 
 import { RbdMirroringService } from '../../../../shared/api/rbd-mirroring.service';
@@ -12,6 +12,7 @@ import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
 import { FinishedTask } from '../../../../shared/models/finished-task';
 import { Permission } from '../../../../shared/models/permissions';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { TaskWrapperService } from '../../../../shared/services/task-wrapper.service';
 import { PoolEditModeModalComponent } from '../pool-edit-mode-modal/pool-edit-mode-modal.component';
 import { PoolEditPeerModalComponent } from '../pool-edit-peer-modal/pool-edit-peer-modal.component';
@@ -31,7 +32,7 @@ export class PoolListComponent implements OnInit, OnDestroy {
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   data: [];
   columns: {};
@@ -39,7 +40,7 @@ export class PoolListComponent implements OnInit, OnDestroy {
   constructor(
     private authStorageService: AuthStorageService,
     private rbdMirroringService: RbdMirroringService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     private i18n: I18n
   ) {
@@ -111,7 +112,7 @@ export class PoolListComponent implements OnInit, OnDestroy {
     const initialState = {
       poolName: this.selection.first().name
     };
-    this.modalRef = this.modalService.show(PoolEditModeModalComponent, { initialState });
+    this.modalRef = this.modalService.show(PoolEditModeModalComponent, initialState);
   }
 
   editPeersModal(mode: string) {
@@ -122,7 +123,7 @@ export class PoolListComponent implements OnInit, OnDestroy {
     if (mode === 'edit') {
       initialState['peerUUID'] = this.getPeerUUID();
     }
-    this.modalRef = this.modalService.show(PoolEditPeerModalComponent, { initialState });
+    this.modalRef = this.modalService.show(PoolEditPeerModalComponent, initialState);
   }
 
   deletePeersModal() {
@@ -130,27 +131,25 @@ export class PoolListComponent implements OnInit, OnDestroy {
     const peerUUID = this.getPeerUUID();
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: this.i18n('mirror peer'),
-        itemNames: [`${poolName} (${peerUUID})`],
-        submitActionObservable: () =>
-          new Observable((observer: Subscriber<any>) => {
-            this.taskWrapper
-              .wrapTaskAroundCall({
-                task: new FinishedTask('rbd/mirroring/peer/delete', {
-                  pool_name: poolName
-                }),
-                call: this.rbdMirroringService.deletePeer(poolName, peerUUID)
-              })
-              .subscribe({
-                error: (resp) => observer.error(resp),
-                complete: () => {
-                  this.rbdMirroringService.refresh();
-                  observer.complete();
-                }
-              });
-          })
-      }
+      itemDescription: this.i18n('mirror peer'),
+      itemNames: [`${poolName} (${peerUUID})`],
+      submitActionObservable: () =>
+        new Observable((observer: Subscriber<any>) => {
+          this.taskWrapper
+            .wrapTaskAroundCall({
+              task: new FinishedTask('rbd/mirroring/peer/delete', {
+                pool_name: poolName
+              }),
+              call: this.rbdMirroringService.deletePeer(poolName, peerUUID)
+            })
+            .subscribe({
+              error: (resp) => observer.error(resp),
+              complete: () => {
+                this.rbdMirroringService.refresh();
+                observer.complete();
+              }
+            });
+        })
     });
   }
 
index b2cbe21a8ae051ad1d9d6ce4505f62987b895504..7533bd7fa0fe079c127188b559c41b6b2ed56609 100644 (file)
@@ -4,7 +4,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
-import { ModalModule } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { BehaviorSubject, of } from 'rxjs';
 
@@ -43,7 +42,6 @@ describe('RbdListComponent', () => {
       BrowserAnimationsModule,
       SharedModule,
       NgbNavModule,
-      ModalModule.forRoot(),
       NgbTooltipModule,
       ToastrModule.forRoot(),
       RouterTestingModule,
index 7a1d9bfa42fb15ae07ddae4e1da69947e2bb5058..b1a72abbbee96b7b3988b45e1be3370d61cc4e68 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { RbdService } from '../../../shared/api/rbd.service';
 import { ListWithDetails } from '../../../shared/classes/list-with-details.class';
@@ -23,6 +23,7 @@ import { Task } from '../../../shared/models/task';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
 import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { URLBuilderService } from '../../../shared/services/url-builder.service';
@@ -63,7 +64,7 @@ export class RbdListComponent extends ListWithDetails implements OnInit {
   viewCacheStatusList: any[];
   selection = new CdTableSelection();
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   builders = {
     'rbd/create': (metadata: object) =>
@@ -104,7 +105,7 @@ export class RbdListComponent extends ListWithDetails implements OnInit {
     private rbdService: RbdService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
     private dimlessPipe: DimlessPipe,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     private taskListService: TaskListService,
     private i18n: I18n,
@@ -339,22 +340,20 @@ export class RbdListComponent extends ListWithDetails implements OnInit {
     const imageSpec = new ImageSpec(poolName, namespace, imageName);
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'RBD',
-        itemNames: [imageSpec],
-        bodyTemplate: this.deleteTpl,
-        bodyContext: {
-          hasSnapshots: this.hasSnapshots(),
-          snapshots: this.listProtectedSnapshots()
-        },
-        submitActionObservable: () =>
-          this.taskWrapper.wrapTaskAroundCall({
-            task: new FinishedTask('rbd/delete', {
-              image_spec: imageSpec.toString()
-            }),
-            call: this.rbdService.delete(imageSpec)
-          })
-      }
+      itemDescription: 'RBD',
+      itemNames: [imageSpec],
+      bodyTemplate: this.deleteTpl,
+      bodyContext: {
+        hasSnapshots: this.hasSnapshots(),
+        snapshots: this.listProtectedSnapshots()
+      },
+      submitActionObservable: () =>
+        this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask('rbd/delete', {
+            image_spec: imageSpec.toString()
+          }),
+          call: this.rbdService.delete(imageSpec)
+        })
     });
   }
 
@@ -365,7 +364,7 @@ export class RbdListComponent extends ListWithDetails implements OnInit {
       imageName: this.selection.first().name,
       hasSnapshots: this.hasSnapshots()
     };
-    this.modalRef = this.modalService.show(RbdTrashMoveModalComponent, { initialState });
+    this.modalRef = this.modalService.show(RbdTrashMoveModalComponent, initialState);
   }
 
   flattenRbd(imageSpec: ImageSpec) {
@@ -378,7 +377,7 @@ export class RbdListComponent extends ListWithDetails implements OnInit {
       })
       .subscribe({
         complete: () => {
-          this.modalRef.hide();
+          this.modalRef.close();
         }
       });
   }
@@ -408,7 +407,7 @@ export class RbdListComponent extends ListWithDetails implements OnInit {
       }
     };
 
-    this.modalRef = this.modalService.show(ConfirmationModalComponent, { initialState });
+    this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState);
   }
 
   hasSnapshots() {
index a7f173bfd3c3ff927d5999550ce27d55a2e80c03..c7a339f344b8b05833e89475322f012fcb4de5c2 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Create Namespace</ng-container>
 
@@ -73,7 +73,7 @@
         <cd-submit-button [form]="namespaceForm"
                           (submitAction)="submit()"
                           i18n>Create Namespace</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Close"
                         i18n-name>
         </cd-back-button>
index 18906016514341816c5d10b3b1e7bf9719a2c6b2..33f486981f759d5ca970556d7994adbcb216c594 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
@@ -24,7 +24,7 @@ describe('RbdNamespaceFormModalComponent', () => {
       RouterTestingModule
     ],
     declarations: [RbdNamespaceFormModalComponent],
-    providers: [BsModalRef, BsModalService, AuthStorageService, i18nProviders]
+    providers: [NgbActiveModal, AuthStorageService, i18nProviders]
   });
 
   beforeEach(() => {
index e25f00667154bee117c1c31cb183d6b13c1a2027..1183c541d7986ee1ff51ddce7199b062e6a8d4bc 100644 (file)
@@ -7,8 +7,8 @@ import {
   ValidatorFn
 } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { Subject } from 'rxjs';
 
 import { PoolService } from '../../../shared/api/pool.service';
@@ -39,7 +39,7 @@ export class RbdNamespaceFormModalComponent implements OnInit {
   public onSubmit: Subject<void>;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private notificationService: NotificationService,
     private poolService: PoolService,
@@ -137,7 +137,7 @@ export class RbdNamespaceFormModalComponent implements OnInit {
             namespace: namespace
           })
         );
-        this.modalRef.hide();
+        this.activeModal.close();
         this.onSubmit.next();
       })
       .catch(() => {
index 50808a48718d7b0cba3d935502722be25523c69f..7857c09f17ec5416b1c07592df3ffc8196498486 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin, Observable } from 'rxjs';
 
 import { PoolService } from '../../../shared/api/pool.service';
@@ -16,6 +16,7 @@ import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { Permission } from '../../../shared/models/permissions';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { RbdNamespaceFormModalComponent } from '../rbd-namespace-form/rbd-namespace-form-modal.component';
@@ -29,7 +30,7 @@ import { RbdNamespaceFormModalComponent } from '../rbd-namespace-form/rbd-namesp
 export class RbdNamespaceListComponent implements OnInit {
   columns: CdTableColumn[];
   namespaces: any;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   permission: Permission;
   selection = new CdTableSelection();
   tableActions: CdTableAction[];
@@ -38,7 +39,7 @@ export class RbdNamespaceListComponent implements OnInit {
     private authStorageService: AuthStorageService,
     private rbdService: RbdService,
     private poolService: PoolService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
@@ -120,7 +121,7 @@ export class RbdNamespaceListComponent implements OnInit {
 
   createModal() {
     this.modalRef = this.modalService.show(RbdNamespaceFormModalComponent);
-    this.modalRef.content.onSubmit.subscribe(() => {
+    this.modalRef.componentInstance.onSubmit.subscribe(() => {
       this.refresh();
     });
   }
@@ -129,27 +130,25 @@ export class RbdNamespaceListComponent implements OnInit {
     const pool = this.selection.first().pool;
     const namespace = this.selection.first().namespace;
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'Namespace',
-        itemNames: [`${pool}/${namespace}`],
-        submitAction: () =>
-          this.rbdService.deleteNamespace(pool, namespace).subscribe(
-            () => {
-              this.notificationService.show(
-                NotificationType.success,
-                this.i18n(`Deleted namespace '{{pool}}/{{namespace}}'`, {
-                  pool: pool,
-                  namespace: namespace
-                })
-              );
-              this.modalRef.hide();
-              this.refresh();
-            },
-            () => {
-              this.modalRef.content.stopLoadingSpinner();
-            }
-          )
-      }
+      itemDescription: 'Namespace',
+      itemNames: [`${pool}/${namespace}`],
+      submitAction: () =>
+        this.rbdService.deleteNamespace(pool, namespace).subscribe(
+          () => {
+            this.notificationService.show(
+              NotificationType.success,
+              this.i18n(`Deleted namespace '{{pool}}/{{namespace}}'`, {
+                pool: pool,
+                namespace: namespace
+              })
+            );
+            this.modalRef.close();
+            this.refresh();
+          },
+          () => {
+            this.modalRef.componentInstance.stopLoadingSpinner();
+          }
+        )
     });
   }
 
index 7a4fc37c4ca885fe367c5894240e2e685a0ea648..ce948ed8d45c60d6edf888ce46c7a1e13443c4da 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n="form title|Example: Create rbdSnapshot@@formTitle"
                 class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
 
@@ -33,7 +33,7 @@
                           i18n="form action button|Example: Create rbdSnapshot@@formActionButton"
                           (submitAction)="submit()">{{ action | titlecase }}
           {{ resource | upperFirst }}</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Close"
                         i18n-name>
         </cd-back-button>
index 6523562e08782e32d1f15be31db5a589c2585492..3e60a3ba787bca4fc489b604fe721d431ec0e4c4 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
@@ -26,7 +26,7 @@ describe('RbdSnapshotFormModalComponent', () => {
       RouterTestingModule
     ],
     declarations: [RbdSnapshotFormModalComponent],
-    providers: [BsModalRef, BsModalService, AuthStorageService, i18nProviders]
+    providers: [NgbActiveModal, AuthStorageService, i18nProviders]
   });
 
   beforeEach(() => {
index d3888074cee5bca27d6d68b85a16b9ea482218f5..f49b72dde5d4ccc39de53eae7b454b6feecfc044 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { Subject } from 'rxjs';
 
 import { RbdService } from '../../../shared/api/rbd.service';
@@ -33,7 +33,7 @@ export class RbdSnapshotFormModalComponent implements OnInit {
   public onSubmit: Subject<string>;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdService: RbdService,
     private taskManagerService: TaskManagerService,
     private notificationService: NotificationService,
@@ -92,7 +92,7 @@ export class RbdSnapshotFormModalComponent implements OnInit {
             this.notificationService.notifyTask(asyncFinishedTask);
           }
         );
-        this.modalRef.hide();
+        this.activeModal.close();
         this.onSubmit.next(this.snapName);
       })
       .catch(() => {
@@ -120,7 +120,7 @@ export class RbdSnapshotFormModalComponent implements OnInit {
             this.notificationService.notifyTask(asyncFinishedTask);
           }
         );
-        this.modalRef.hide();
+        this.activeModal.close();
         this.onSubmit.next(snapshotName);
       })
       .catch(() => {
index f1603d6364ab7750e721d8255986e683e7d9615a..fc08cba070439f1e447f3fbf0e65c776dbe78ff1 100644 (file)
@@ -3,9 +3,10 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testin
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import { NgbModalModule, NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
+import { MockComponent } from 'ng-mocks';
 import { ToastrModule } from 'ngx-toastr';
 import { Subject, throwError as observableThrowError } from 'rxjs';
 
@@ -17,13 +18,16 @@ import {
 } from '../../../../testing/unit-test-helper';
 import { RbdService } from '../../../shared/api/rbd.service';
 import { ComponentsModule } from '../../../shared/components/components.module';
+import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
 import { DataTableModule } from '../../../shared/datatable/datatable.module';
 import { TableActionsComponent } from '../../../shared/datatable/table-actions/table-actions.component';
+import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { Permissions } from '../../../shared/models/permissions';
 import { PipesModule } from '../../../shared/pipes/pipes.module';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { SummaryService } from '../../../shared/services/summary.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
@@ -46,24 +50,33 @@ describe('RbdSnapshotListComponent', () => {
     }
   };
 
-  configureTestBed({
-    declarations: [RbdSnapshotListComponent, RbdTabsComponent],
-    imports: [
-      BrowserAnimationsModule,
-      ComponentsModule,
-      DataTableModule,
-      HttpClientTestingModule,
-      PipesModule,
-      RouterTestingModule,
-      NgbNavModule,
-      ToastrModule.forRoot()
-    ],
-    providers: [
-      { provide: AuthStorageService, useValue: fakeAuthStorageService },
-      TaskListService,
-      i18nProviders
-    ]
-  });
+  configureTestBed(
+    {
+      declarations: [
+        RbdSnapshotListComponent,
+        RbdTabsComponent,
+        MockComponent(RbdSnapshotFormModalComponent)
+      ],
+      imports: [
+        BrowserAnimationsModule,
+        ComponentsModule,
+        DataTableModule,
+        HttpClientTestingModule,
+        PipesModule,
+        RouterTestingModule,
+        NgbNavModule,
+        ToastrModule.forRoot(),
+        NgbModalModule,
+        NgBootstrapFormValidationModule.forRoot()
+      ],
+      providers: [
+        { provide: AuthStorageService, useValue: fakeAuthStorageService },
+        TaskListService,
+        i18nProviders
+      ]
+    },
+    [CriticalConfirmationModalComponent]
+  );
 
   beforeEach(() => {
     fixture = TestBed.createComponent(RbdSnapshotListComponent);
@@ -86,6 +99,7 @@ describe('RbdSnapshotListComponent', () => {
     beforeEach(() => {
       fixture.detectChanges();
       const i18n = TestBed.inject(I18n);
+      const modalService = TestBed.inject(ModalService);
       const actionLabelsI18n = TestBed.inject(ActionLabelsI18n);
       called = false;
       rbdService = new RbdService(null, null);
@@ -94,7 +108,7 @@ describe('RbdSnapshotListComponent', () => {
       authStorageService.set('user', '', { 'rbd-image': ['create', 'read', 'update', 'delete'] });
       component = new RbdSnapshotListComponent(
         authStorageService,
-        null,
+        modalService,
         null,
         null,
         rbdService,
@@ -107,15 +121,16 @@ describe('RbdSnapshotListComponent', () => {
       );
       spyOn(rbdService, 'deleteSnapshot').and.returnValue(observableThrowError({ status: 500 }));
       spyOn(notificationService, 'notifyTask').and.stub();
-      component.modalRef = new BsModalRef();
-      component.modalRef.content = {
-        stopLoadingSpinner: () => (called = true)
-      };
     });
 
     it('should call stopLoadingSpinner if the request fails', fakeAsync(() => {
+      component.updateSelection(new CdTableSelection([{ name: 'someName' }]));
       expect(called).toBe(false);
-      component._asyncTask('deleteSnapshot', 'rbd/snap/delete', 'someName');
+      component.deleteSnapshotModal();
+      spyOn(component.modalRef.componentInstance, 'stopLoadingSpinner').and.callFake(() => {
+        called = true;
+      });
+      component.modalRef.componentInstance.submitAction();
       tick(500);
       expect(called).toBe(true);
     }));
@@ -188,9 +203,9 @@ describe('RbdSnapshotListComponent', () => {
     beforeEach(() => {
       component.poolName = 'pool01';
       component.rbdName = 'image01';
-      spyOn(TestBed.inject(BsModalService), 'show').and.callFake(() => {
-        const ref = new BsModalRef();
-        ref.content = new RbdSnapshotFormModalComponent(
+      spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => {
+        const ref: any = {};
+        ref.componentInstance = new RbdSnapshotFormModalComponent(
           null,
           null,
           null,
@@ -198,7 +213,7 @@ describe('RbdSnapshotListComponent', () => {
           TestBed.inject(I18n),
           TestBed.inject(ActionLabelsI18n)
         );
-        ref.content.onSubmit = new Subject();
+        ref.componentInstance.onSubmit = new Subject();
         return ref;
       });
     });
@@ -206,13 +221,13 @@ describe('RbdSnapshotListComponent', () => {
     it('should display old snapshot name', () => {
       component.selection.selected = [{ name: 'oldname' }];
       component.openEditSnapshotModal();
-      expect(component.modalRef.content.snapName).toBe('oldname');
-      expect(component.modalRef.content.editing).toBeTruthy();
+      expect(component.modalRef.componentInstance.snapName).toBe('oldname');
+      expect(component.modalRef.componentInstance.editing).toBeTruthy();
     });
 
     it('should display suggested snapshot name', () => {
       component.openCreateSnapshotModal();
-      expect(component.modalRef.content.snapName).toMatch(
+      expect(component.modalRef.componentInstance.snapName).toMatch(
         RegExp(`^${component.rbdName}_[\\d-]+T[\\d.:]+[\\+-][\\d:]+$`)
       );
     });
index 2d577d169e8c357927c2c99b0d863f214e092933..8c3a1fc433721bd37cbc591ec74edb6a4437a5c1 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as moment from 'moment';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { of } from 'rxjs';
 
 import { RbdService } from '../../../shared/api/rbd.service';
@@ -21,6 +21,7 @@ import { Task } from '../../../shared/models/task';
 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { SummaryService } from '../../../shared/services/summary.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
@@ -59,7 +60,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
 
   columns: CdTableColumn[];
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   builders = {
     'rbd/snap/create': (metadata: any) => {
@@ -71,7 +72,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
 
   constructor(
     private authStorageService: AuthStorageService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
     private cdDatePipe: CdDatePipe,
     private rbdService: RbdService,
@@ -170,18 +171,18 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
 
   private openSnapshotModal(taskName: string, snapName: string = null) {
     this.modalRef = this.modalService.show(RbdSnapshotFormModalComponent);
-    this.modalRef.content.poolName = this.poolName;
-    this.modalRef.content.imageName = this.rbdName;
-    this.modalRef.content.namespace = this.namespace;
+    this.modalRef.componentInstance.poolName = this.poolName;
+    this.modalRef.componentInstance.imageName = this.rbdName;
+    this.modalRef.componentInstance.namespace = this.namespace;
     if (snapName) {
-      this.modalRef.content.setEditing();
+      this.modalRef.componentInstance.setEditing();
     } else {
       // Auto-create a name for the snapshot: <image_name>_<timestamp_ISO_8601>
       // https://en.wikipedia.org/wiki/ISO_8601
       snapName = `${this.rbdName}_${moment().toISOString(true)}`;
     }
-    this.modalRef.content.setSnapName(snapName);
-    this.modalRef.content.onSubmit.subscribe((snapshotName: string) => {
+    this.modalRef.componentInstance.setSnapName(snapName);
+    this.modalRef.componentInstance.onSubmit.subscribe((snapshotName: string) => {
       const executingTask = new ExecutingTask();
       executingTask.name = taskName;
       executingTask.metadata = {
@@ -246,7 +247,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
         executingTask.name = finishedTask.name;
         executingTask.metadata = finishedTask.metadata;
         this.summaryService.addRunningTask(executingTask);
-        this.modalRef.hide();
+        this.modalRef.close();
         this.ngOnChanges();
         this.taskManagerService.subscribe(
           executingTask.name,
@@ -257,7 +258,7 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
         );
       })
       .catch(() => {
-        this.modalRef.content.stopLoadingSpinner();
+        this.modalRef.componentInstance.stopLoadingSpinner();
       });
   }
 
@@ -276,17 +277,15 @@ export class RbdSnapshotListComponent implements OnInit, OnChanges {
       }
     };
 
-    this.modalRef = this.modalService.show(ConfirmationModalComponent, { initialState });
+    this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState);
   }
 
   deleteSnapshotModal() {
     const snapshotName = this.selection.selected[0].name;
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: this.i18n('RBD snapshot'),
-        itemNames: [snapshotName],
-        submitAction: () => this._asyncTask('deleteSnapshot', 'rbd/snap/delete', snapshotName)
-      }
+      itemDescription: this.i18n('RBD snapshot'),
+      itemNames: [snapshotName],
+      submitAction: () => this._asyncTask('deleteSnapshot', 'rbd/snap/delete', snapshotName)
     });
   }
 
index ebbf28768c446b4679ec355ecc3e3728103bc8e4..9b6b3b44b89ce723d16731d2587abce0d9513e5b 100644 (file)
@@ -1,9 +1,9 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
 import * as moment from 'moment';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { RbdService } from '../../../shared/api/rbd.service';
 import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
@@ -22,6 +22,7 @@ import { Permission } from '../../../shared/models/permissions';
 import { Task } from '../../../shared/models/task';
 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { RbdTrashPurgeModalComponent } from '../rbd-trash-purge-modal/rbd-trash-purge-modal.component';
@@ -46,7 +47,7 @@ export class RbdTrashListComponent implements OnInit {
   columns: CdTableColumn[];
   executingTasks: ExecutingTask[] = [];
   images: any;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   permission: Permission;
   retries: number;
   selection = new CdTableSelection();
@@ -57,7 +58,7 @@ export class RbdTrashListComponent implements OnInit {
   constructor(
     private authStorageService: AuthStorageService,
     private rbdService: RbdService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private cdDatePipe: CdDatePipe,
     private taskListService: TaskListService,
     private taskWrapper: TaskWrapperService,
@@ -184,7 +185,7 @@ export class RbdTrashListComponent implements OnInit {
       imageId: this.selection.first().id
     };
 
-    this.modalRef = this.modalService.show(RbdTrashRestoreModalComponent, { initialState });
+    this.modalRef = this.modalService.show(RbdTrashRestoreModalComponent, initialState);
   }
 
   deleteModal() {
@@ -195,19 +196,17 @@ export class RbdTrashListComponent implements OnInit {
     const imageIdSpec = new ImageSpec(poolName, namespace, imageId);
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'RBD',
-        itemNames: [imageIdSpec],
-        bodyTemplate: this.deleteTpl,
-        bodyContext: { $implicit: expiresAt },
-        submitActionObservable: () =>
-          this.taskWrapper.wrapTaskAroundCall({
-            task: new FinishedTask('rbd/trash/remove', {
-              image_id_spec: imageIdSpec.toString()
-            }),
-            call: this.rbdService.removeTrash(imageIdSpec, true)
-          })
-      }
+      itemDescription: 'RBD',
+      itemNames: [imageIdSpec],
+      bodyTemplate: this.deleteTpl,
+      bodyContext: { $implicit: expiresAt },
+      submitActionObservable: () =>
+        this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask('rbd/trash/remove', {
+            image_id_spec: imageIdSpec.toString()
+          }),
+          call: this.rbdService.removeTrash(imageIdSpec, true)
+        })
     });
   }
 
index b6103e6502bcdae355571c5b971748f1a21c748b..2bd0bdcd9f81e10afbf9d1dbdbb16fabbb0e3382 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Move an image to trash</ng-container>
 
@@ -44,7 +44,7 @@
         <cd-submit-button i18n
                           [form]="moveForm"
                           (submitAction)="moveImage()">Move Image</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index d9e9e2d7ab8d1280c52bf7f5d4a4a45d22e8a722..05f61c4d99f43f3370cb2104a98769dd4207184c 100644 (file)
@@ -3,9 +3,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as moment from 'moment';
 import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
@@ -28,7 +28,7 @@ describe('RbdTrashMoveModalComponent', () => {
       BsDatepickerModule.forRoot()
     ],
     declarations: [RbdTrashMoveModalComponent],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -57,12 +57,12 @@ describe('RbdTrashMoveModalComponent', () => {
     beforeEach(() => {
       notificationService = TestBed.inject(NotificationService);
       spyOn(notificationService, 'show').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
     });
 
     afterEach(() => {
       expect(notificationService.show).toHaveBeenCalledTimes(1);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('with normal delay', () => {
index 17ac15d85841adf3900e972711e2f1e75d8ad975..3071c0186c495771f1d5a2f722e4567ac25bc299 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as moment from 'moment';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { RbdService } from '../../../shared/api/rbd.service';
 import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
@@ -38,7 +38,7 @@ export class RbdTrashMoveModalComponent implements OnInit {
 
   constructor(
     private rbdService: RbdService,
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private fb: CdFormBuilder,
     private taskWrapper: TaskWrapperService
   ) {
@@ -90,7 +90,7 @@ export class RbdTrashMoveModalComponent implements OnInit {
       })
       .subscribe({
         complete: () => {
-          this.modalRef.hide();
+          this.activeModal.close();
         }
       });
   }
index fa68cdf987c4333eb31eb1cfb7f966086149ccb3..692014a386299a9042ec2e71ee1e1fcca8e249bc 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Purge Trash</ng-container>
 
@@ -43,7 +43,7 @@
                           [form]="purgeForm"
                           (submitAction)="purge()"
                           i18n>Purge Trash</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index d8ea8d05e5af656db764a21700f75594bd1c6fdf..fbecde705cc4392836a485f1c7153c8e435bcd8c 100644 (file)
@@ -7,7 +7,7 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testin
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
@@ -30,7 +30,7 @@ describe('RbdTrashPurgeModalComponent', () => {
       RouterTestingModule
     ],
     declarations: [RbdTrashPurgeModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -71,17 +71,17 @@ describe('RbdTrashPurgeModalComponent', () => {
 
   describe('should call purge', () => {
     let notificationService: NotificationService;
-    let modalRef: BsModalRef;
+    let activeModal: NgbActiveModal;
     let req: TestRequest;
 
     beforeEach(() => {
       fixture.detectChanges();
       notificationService = TestBed.inject(NotificationService);
-      modalRef = TestBed.inject(BsModalRef);
+      activeModal = TestBed.inject(NgbActiveModal);
 
       component.purgeForm.patchValue({ poolName: 'foo' });
 
-      spyOn(modalRef, 'hide').and.stub();
+      spyOn(activeModal, 'close').and.stub();
       spyOn(component.purgeForm, 'setErrors').and.stub();
       spyOn(notificationService, 'show').and.stub();
 
@@ -93,13 +93,13 @@ describe('RbdTrashPurgeModalComponent', () => {
     it('with success', () => {
       req.flush(null);
       expect(component.purgeForm.setErrors).toHaveBeenCalledTimes(0);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('with failure', () => {
       req.flush(null, { status: 500, statusText: 'failure' });
       expect(component.purgeForm.setErrors).toHaveBeenCalledTimes(1);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(0);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(0);
     });
   });
 });
index e0f95cb5c1b89f20c9b97e49e4a84c3e0dd11224..0da8685cf1c57eae6159e681d5026f00b667114b 100644 (file)
@@ -1,6 +1,6 @@
 import { Component, OnInit } from '@angular/core';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { PoolService } from '../../../shared/api/pool.service';
 import { RbdService } from '../../../shared/api/rbd.service';
@@ -25,7 +25,7 @@ export class RbdTrashPurgeModalComponent implements OnInit {
   constructor(
     private authStorageService: AuthStorageService,
     private rbdService: RbdService,
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private fb: CdFormBuilder,
     private poolService: PoolService,
     private taskWrapper: TaskWrapperService
@@ -65,7 +65,7 @@ export class RbdTrashPurgeModalComponent implements OnInit {
           this.purgeForm.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.modalRef.hide();
+          this.activeModal.close();
         }
       });
   }
index 17929b792f023a0e00377b429e6d63e9b872518c..6aa4105d0d0cd5a7ec0323b02d69b15e85c0f493 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Restore Image</ng-container>
 
@@ -37,7 +37,7 @@
         <cd-submit-button [form]="restoreForm"
                           (submitAction)="restore()"
                           i18n>Restore Image</cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 01808b6cf95feac9fc817ab66cfb4c3afe392612..7878e7e8139b5d186b1b807af694e28e1292708d 100644 (file)
@@ -7,7 +7,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
@@ -28,7 +28,7 @@ describe('RbdTrashRestoreModalComponent', () => {
       SharedModule,
       RouterTestingModule
     ],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
@@ -44,20 +44,20 @@ describe('RbdTrashRestoreModalComponent', () => {
   describe('should call restore', () => {
     let httpTesting: HttpTestingController;
     let notificationService: NotificationService;
-    let modalRef: BsModalRef;
+    let activeModal: NgbActiveModal;
     let req: TestRequest;
 
     beforeEach(() => {
       httpTesting = TestBed.inject(HttpTestingController);
       notificationService = TestBed.inject(NotificationService);
-      modalRef = TestBed.inject(BsModalRef);
+      activeModal = TestBed.inject(NgbActiveModal);
 
       component.poolName = 'foo';
       component.imageName = 'bar';
       component.imageId = '113cb6963793';
       component.ngOnInit();
 
-      spyOn(modalRef, 'hide').and.stub();
+      spyOn(activeModal, 'close').and.stub();
       spyOn(component.restoreForm, 'setErrors').and.stub();
       spyOn(notificationService, 'show').and.stub();
 
@@ -69,13 +69,13 @@ describe('RbdTrashRestoreModalComponent', () => {
     it('with success', () => {
       req.flush(null);
       expect(component.restoreForm.setErrors).toHaveBeenCalledTimes(0);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('with failure', () => {
       req.flush(null, { status: 500, statusText: 'failure' });
       expect(component.restoreForm.setErrors).toHaveBeenCalledTimes(1);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(0);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(0);
     });
   });
 });
index 6392d31c05f12a0dcccd59754ede6e757ff07f8b..869740ae54241835995d255443630e86a68d051b 100644 (file)
@@ -1,6 +1,6 @@
 import { Component, OnInit } from '@angular/core';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { RbdService } from '../../../shared/api/rbd.service';
 import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
@@ -27,7 +27,7 @@ export class RbdTrashRestoreModalComponent implements OnInit {
 
   constructor(
     private rbdService: RbdService,
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private fb: CdFormBuilder,
     private taskWrapper: TaskWrapperService
   ) {}
@@ -56,7 +56,7 @@ export class RbdTrashRestoreModalComponent implements OnInit {
           this.restoreForm.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.modalRef.hide();
+          this.activeModal.close();
         }
       });
   }
index c4041af1c5972449e7f0b192b40d70330044de9f..305dcbca4e94a0f6fb1cc9d6c73665966bb15a87 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { CephfsService } from '../../../shared/api/cephfs.service';
 import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
@@ -14,6 +14,7 @@ import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { Permission } from '../../../shared/models/permissions';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 
 @Component({
@@ -38,13 +39,13 @@ export class CephfsClientsComponent implements OnInit {
 
   permission: Permission;
   tableActions: CdTableAction[];
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   selection = new CdTableSelection();
 
   constructor(
     private cephfsService: CephfsService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private authStorageService: AuthStorageService,
     private i18n: I18n,
@@ -79,14 +80,14 @@ export class CephfsClientsComponent implements OnInit {
     this.cephfsService.evictClient(this.id, clientId).subscribe(
       () => {
         this.triggerApiUpdate.emit();
-        this.modalRef.hide();
+        this.modalRef.close();
         this.notificationService.show(
           NotificationType.success,
           this.i18n(`Evicted client '{{clientId}}'`, { clientId: clientId })
         );
       },
       () => {
-        this.modalRef.content.stopLoadingSpinner();
+        this.modalRef.componentInstance.stopLoadingSpinner();
       }
     );
   }
@@ -94,12 +95,10 @@ export class CephfsClientsComponent implements OnInit {
   evictClientModal() {
     const clientId = this.selection.first().id;
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'client',
-        itemNames: [clientId],
-        actionDescription: 'evict',
-        submitAction: () => this.evictClient(clientId)
-      }
+      itemDescription: 'client',
+      itemNames: [clientId],
+      actionDescription: 'evict',
+      submitAction: () => this.evictClient(clientId)
     });
   }
 }
index 4017453b3b9e4c4fcea0eb49672db35bedebe195..4382f630ad77a6a10675ad891f35bed03079659f 100644 (file)
@@ -4,9 +4,9 @@ import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testin
 import { Validators } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { TreeComponent, TreeModule, TREE_ACTIONS } from 'angular-tree-component';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
-import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { Observable, of } from 'rxjs';
 
@@ -18,6 +18,7 @@ import {
 } from '../../../../testing/unit-test-helper';
 import { CephfsService } from '../../../shared/api/cephfs.service';
 import { ConfirmationModalComponent } from '../../../shared/components/confirmation-modal/confirmation-modal.component';
+import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
 import { FormModalComponent } from '../../../shared/components/form-modal/form-modal.component';
 import { NotificationType } from '../../../shared/enum/notification-type.enum';
 import { CdValidators } from '../../../shared/forms/cd-validators';
@@ -28,6 +29,7 @@ import {
   CephfsQuotas,
   CephfsSnapshot
 } from '../../../shared/models/cephfs-directory-models';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { CephfsDirectoriesComponent } from './cephfs-directories.component';
@@ -44,7 +46,7 @@ describe('CephfsDirectoriesComponent', () => {
   let maxValidator: jasmine.Spy;
   let minBinaryValidator: jasmine.Spy;
   let maxBinaryValidator: jasmine.Spy;
-  let modal: any;
+  let modal: NgbModalRef;
 
   // Get's private attributes or functions
   const get = {
@@ -156,7 +158,7 @@ describe('CephfsDirectoriesComponent', () => {
     },
     modalShow: (comp: Type<any>, init: any): any => {
       modal = modalServiceShow(comp, init);
-      return modal.ref;
+      return modal;
     },
     getNodeById: (path: string) => {
       return mockLib.useNode(path);
@@ -210,26 +212,26 @@ describe('CephfsDirectoriesComponent', () => {
     },
     createSnapshotThroughModal: (name: string) => {
       component.createSnapshot();
-      modal.component.onSubmitForm({ name });
+      modal.componentInstance.onSubmitForm({ name });
     },
     deleteSnapshotsThroughModal: (snapshots: CephfsSnapshot[]) => {
       component.snapshot.selection.selected = snapshots;
       component.deleteSnapshotModal();
-      modal.component.callSubmitAction();
+      modal.componentInstance.callSubmitAction();
     },
     updateQuotaThroughModal: (attribute: string, value: number) => {
       component.quota.selection.selected = component.settings.filter(
         (q) => q.quotaKey === attribute
       );
       component.updateQuotaModal();
-      modal.component.onSubmitForm({ [attribute]: value });
+      modal.componentInstance.onSubmitForm({ [attribute]: value });
     },
     unsetQuotaThroughModal: (attribute: string) => {
       component.quota.selection.selected = component.settings.filter(
         (q) => q.quotaKey === attribute
       );
       component.unsetQuotaModal();
-      modal.component.onSubmit();
+      modal.componentInstance.onSubmit();
     },
     setFourQuotaDirs: (quotas: number[][]) => {
       expect(quotas.length).toBe(4); // Make sure this function is used correctly
@@ -306,23 +308,25 @@ describe('CephfsDirectoriesComponent', () => {
       });
     },
     quotaUnsetModalTexts: (titleText: string, message: string, notificationMsg: string) => {
-      expect(modalShowSpy).toHaveBeenCalledWith(ConfirmationModalComponent, {
-        initialState: expect.objectContaining({
+      expect(modalShowSpy).toHaveBeenCalledWith(
+        ConfirmationModalComponent,
+        expect.objectContaining({
           titleText,
           description: message,
           buttonText: 'Unset'
         })
-      });
+      );
       expect(notificationShowSpy).toHaveBeenCalledWith(NotificationType.success, notificationMsg);
     },
     quotaUpdateModalTexts: (titleText: string, message: string, notificationMsg: string) => {
-      expect(modalShowSpy).toHaveBeenCalledWith(FormModalComponent, {
-        initialState: expect.objectContaining({
+      expect(modalShowSpy).toHaveBeenCalledWith(
+        FormModalComponent,
+        expect.objectContaining({
           titleText,
           message,
           submitButtonText: 'Save'
         })
-      });
+      );
       expect(notificationShowSpy).toHaveBeenCalledWith(NotificationType.success, notificationMsg);
     },
     quotaUpdateModalField: (
@@ -333,8 +337,9 @@ describe('CephfsDirectoriesComponent', () => {
       max: number,
       errors?: { [key: string]: string }
     ) => {
-      expect(modalShowSpy).toHaveBeenCalledWith(FormModalComponent, {
-        initialState: expect.objectContaining({
+      expect(modalShowSpy).toHaveBeenCalledWith(
+        FormModalComponent,
+        expect.objectContaining({
           fields: [
             {
               type,
@@ -347,7 +352,7 @@ describe('CephfsDirectoriesComponent', () => {
             }
           ]
         })
-      });
+      );
       if (type === 'binary') {
         expect(minBinaryValidator).toHaveBeenCalledWith(0);
         expect(maxBinaryValidator).toHaveBeenCalledWith(max);
@@ -358,19 +363,22 @@ describe('CephfsDirectoriesComponent', () => {
     }
   };
 
-  configureTestBed({
-    imports: [
-      HttpClientTestingModule,
-      SharedModule,
-      RouterTestingModule,
-      TreeModule.forRoot(),
-      NgBootstrapFormValidationModule.forRoot(),
-      ToastrModule.forRoot(),
-      ModalModule.forRoot()
-    ],
-    declarations: [CephfsDirectoriesComponent],
-    providers: [i18nProviders, BsModalRef]
-  });
+  configureTestBed(
+    {
+      imports: [
+        HttpClientTestingModule,
+        SharedModule,
+        RouterTestingModule,
+        TreeModule.forRoot(),
+        NgBootstrapFormValidationModule.forRoot(),
+        ToastrModule.forRoot(),
+        NgbModalModule
+      ],
+      declarations: [CephfsDirectoriesComponent],
+      providers: [i18nProviders, NgbActiveModal]
+    },
+    [CriticalConfirmationModalComponent, FormModalComponent, ConfirmationModalComponent]
+  );
 
   beforeEach(() => {
     noAsyncUpdate = false;
@@ -389,7 +397,7 @@ describe('CephfsDirectoriesComponent', () => {
     spyOn(cephfsService, 'rmSnapshot').and.callFake(mockLib.rmSnapshot);
     spyOn(cephfsService, 'updateQuota').and.callFake(mockLib.updateQuota);
 
-    modalShowSpy = spyOn(TestBed.inject(BsModalService), 'show').and.callFake(mockLib.modalShow);
+    modalShowSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake(mockLib.modalShow);
     notificationShowSpy = spyOn(TestBed.inject(NotificationService), 'show').and.stub();
 
     fixture = TestBed.createComponent(CephfsDirectoriesComponent);
index e9db99eed52ffb1b2c85f02356a4623b07b575f1..df6ae3a250f6bbea0047cb20d18e58f75e1c02a3 100644 (file)
@@ -1,6 +1,7 @@
 import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@angular/core';
 import { Validators } from '@angular/forms';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import {
   ITreeOptions,
@@ -11,7 +12,6 @@ import {
 } from 'angular-tree-component';
 import * as _ from 'lodash';
 import * as moment from 'moment';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { CephfsService } from '../../../shared/api/cephfs.service';
 import { ConfirmationModalComponent } from '../../../shared/components/confirmation-modal/confirmation-modal.component';
@@ -34,6 +34,7 @@ import { Permission } from '../../../shared/models/permissions';
 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 
 class QuotaSetting {
@@ -65,7 +66,7 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges {
   @Input()
   id: number;
 
-  private modalRef: BsModalRef;
+  private modalRef: NgbModalRef;
   private dirs: CephfsDir[];
   private nodeIds: { [path: string]: CephfsDir };
   private requestedPaths: string[];
@@ -106,7 +107,7 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges {
 
   constructor(
     private authStorageService: AuthStorageService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private cephfsService: CephfsService,
     private cdDatePipe: CdDatePipe,
     private i18n: I18n,
@@ -416,20 +417,18 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges {
     const key = selection.quotaKey;
     const value = selection.dirValue;
     this.modalService.show(FormModalComponent, {
-      initialState: {
-        titleText: this.getModalQuotaTitle(
-          value === 0 ? this.actionLabels.SET : this.actionLabels.UPDATE,
-          path
-        ),
-        message: nextMax.value
-          ? this.i18n('The inherited {{quotaValue}} is the maximum value to be used.', {
-              quotaValue: this.getQuotaValueFromPathMsg(nextMax.value, nextMax.path)
-            })
-          : undefined,
-        fields: [this.getQuotaFormField(selection.row.name, key, value, nextMax.value)],
-        submitButtonText: this.i18n('Save'),
-        onSubmit: (values: CephfsQuotas) => this.updateQuota(values)
-      }
+      titleText: this.getModalQuotaTitle(
+        value === 0 ? this.actionLabels.SET : this.actionLabels.UPDATE,
+        path
+      ),
+      message: nextMax.value
+        ? this.i18n('The inherited {{quotaValue}} is the maximum value to be used.', {
+            quotaValue: this.getQuotaValueFromPathMsg(nextMax.value, nextMax.path)
+          })
+        : undefined,
+      fields: [this.getQuotaFormField(selection.row.name, key, value, nextMax.value)],
+      submitButtonText: this.i18n('Save'),
+      onSubmit: (values: CephfsQuotas) => this.updateQuota(values)
     });
   }
 
@@ -514,25 +513,23 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges {
     const dirValue = selection.dirValue;
 
     this.modalRef = this.modalService.show(ConfirmationModalComponent, {
-      initialState: {
-        titleText: this.getModalQuotaTitle(this.actionLabels.UNSET, path),
-        buttonText: this.actionLabels.UNSET,
-        description: this.i18n(`{{action}} {{quotaValue}} {{conclusion}}.`, {
-          action: this.actionLabels.UNSET,
-          quotaValue: this.getQuotaValueFromPathMsg(dirValue, path),
-          conclusion:
-            nextMax.value > 0
-              ? nextMax.value > dirValue
-                ? this.i18n('in order to inherit {{quotaValue}}', {
-                    quotaValue: this.getQuotaValueFromPathMsg(nextMax.value, nextMax.path)
-                  })
-                : this.i18n(`which isn't used because of the inheritance of {{quotaValue}}`, {
-                    quotaValue: this.getQuotaValueFromPathMsg(nextMax.value, nextMax.path)
-                  })
-              : this.i18n('in order to have no quota on the directory')
-        }),
-        onSubmit: () => this.updateQuota({ [key]: 0 }, () => this.modalRef.hide())
-      }
+      titleText: this.getModalQuotaTitle(this.actionLabels.UNSET, path),
+      buttonText: this.actionLabels.UNSET,
+      description: this.i18n(`{{action}} {{quotaValue}} {{conclusion}}.`, {
+        action: this.actionLabels.UNSET,
+        quotaValue: this.getQuotaValueFromPathMsg(dirValue, path),
+        conclusion:
+          nextMax.value > 0
+            ? nextMax.value > dirValue
+              ? this.i18n('in order to inherit {{quotaValue}}', {
+                  quotaValue: this.getQuotaValueFromPathMsg(nextMax.value, nextMax.path)
+                })
+              : this.i18n(`which isn't used because of the inheritance of {{quotaValue}}`, {
+                  quotaValue: this.getQuotaValueFromPathMsg(nextMax.value, nextMax.path)
+                })
+            : this.i18n('in order to have no quota on the directory')
+      }),
+      onSubmit: () => this.updateQuota({ [key]: 0 }, () => this.modalRef.close())
     });
   }
 
@@ -540,30 +537,28 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges {
     // Create a snapshot. Auto-generate a snapshot name by default.
     const path = this.selectedDir.path;
     this.modalService.show(FormModalComponent, {
-      initialState: {
-        titleText: this.i18n('Create Snapshot'),
-        message: this.i18n('Please enter the name of the snapshot.'),
-        fields: [
-          {
-            type: 'text',
-            name: 'name',
-            value: `${moment().toISOString(true)}`,
-            required: true
-          }
-        ],
-        submitButtonText: this.i18n('Create Snapshot'),
-        onSubmit: (values: CephfsSnapshot) => {
-          this.cephfsService.mkSnapshot(this.id, path, values.name).subscribe((name) => {
-            this.notificationService.show(
-              NotificationType.success,
-              this.i18n(`Created snapshot '{{name}}' for '{{path}}'`, {
-                name: name,
-                path: path
-              })
-            );
-            this.forceDirRefresh();
-          });
+      titleText: this.i18n('Create Snapshot'),
+      message: this.i18n('Please enter the name of the snapshot.'),
+      fields: [
+        {
+          type: 'text',
+          name: 'name',
+          value: `${moment().toISOString(true)}`,
+          required: true
         }
+      ],
+      submitButtonText: this.i18n('Create Snapshot'),
+      onSubmit: (values: CephfsSnapshot) => {
+        this.cephfsService.mkSnapshot(this.id, path, values.name).subscribe((name) => {
+          this.notificationService.show(
+            NotificationType.success,
+            this.i18n(`Created snapshot '{{name}}' for '{{path}}'`, {
+              name: name,
+              path: path
+            })
+          );
+          this.forceDirRefresh();
+        });
       }
     });
   }
@@ -673,13 +668,9 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges {
 
   deleteSnapshotModal() {
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: this.i18n('CephFs Snapshot'),
-        itemNames: this.snapshot.selection.selected.map(
-          (snapshot: CephfsSnapshot) => snapshot.name
-        ),
-        submitAction: () => this.deleteSnapshot()
-      }
+      itemDescription: this.i18n('CephFs Snapshot'),
+      itemNames: this.snapshot.selection.selected.map((snapshot: CephfsSnapshot) => snapshot.name),
+      submitAction: () => this.deleteSnapshot()
     });
   }
 
@@ -697,7 +688,7 @@ export class CephfsDirectoriesComponent implements OnInit, OnChanges {
         );
       });
     });
-    this.modalRef.hide();
+    this.modalRef.close();
     this.forceDirRefresh();
   }
 
index 28dc7b91d69e9ae8b4d838d6692b306f7cdef22e..4a5f7e58cb831b24cc848d5a4a655171a197b073 100644 (file)
@@ -7,7 +7,6 @@ import { NgbNavModule, NgbTooltipModule, NgbTypeaheadModule } from '@ng-bootstra
 import { TreeModule } from 'angular-tree-component';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
 import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
-import { ModalModule } from 'ngx-bootstrap/modal';
 import { TimepickerModule } from 'ngx-bootstrap/timepicker';
 
 import { SharedModule } from '../../shared/shared.module';
@@ -58,7 +57,6 @@ import { TelemetryComponent } from './telemetry/telemetry.component';
     FormsModule,
     ReactiveFormsModule,
     BsDatepickerModule.forRoot(),
-    ModalModule.forRoot(),
     NgbTooltipModule,
     MgrModulesModule,
     NgbTypeaheadModule,
index 41594c1f55e7924504adb5cd137c36e031cafd19..6648eff498b18a0b4885d72e749d7bdab5a62ccc 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 import { Router } from '@angular/router';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { HostService } from '../../../shared/api/host.service';
 import { ListWithDetails } from '../../../shared/classes/list-with-details.class';
@@ -23,6 +23,7 @@ import { CephShortVersionPipe } from '../../../shared/pipes/ceph-short-version.p
 import { JoinPipe } from '../../../shared/pipes/join.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
 import { DepCheckerService } from '../../../shared/services/dep-checker.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { URLBuilderService } from '../../../shared/services/url-builder.service';
@@ -48,7 +49,7 @@ export class HostsComponent extends ListWithDetails implements OnInit {
   cdParams = { fromLink: '/hosts' };
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   constructor(
     private authStorageService: AuthStorageService,
@@ -58,7 +59,7 @@ export class HostsComponent extends ListWithDetails implements OnInit {
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     private actionLabels: ActionLabelsI18n,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     private router: Router,
     private depCheckerService: DepCheckerService,
@@ -199,16 +200,14 @@ export class HostsComponent extends ListWithDetails implements OnInit {
   deleteAction() {
     const hostname = this.selection.first().hostname;
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'Host',
-        itemNames: [hostname],
-        actionDescription: 'delete',
-        submitActionObservable: () =>
-          this.taskWrapper.wrapTaskAroundCall({
-            task: new FinishedTask('host/delete', { hostname: hostname }),
-            call: this.hostService.delete(hostname)
-          })
-      }
+      itemDescription: 'Host',
+      itemNames: [hostname],
+      actionDescription: 'delete',
+      submitActionObservable: () =>
+        this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask('host/delete', { hostname: hostname }),
+          call: this.hostService.delete(hostname)
+        })
     });
   }
 
index 1a48903510c1a46aceccd9a93d694bbe77377c22..42559e24198f907d1521a9e7536a8326ced02aa2 100644 (file)
@@ -10,7 +10,6 @@ import {
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { Subscription } from 'rxjs';
 
 import { OrchestratorService } from '../../../../shared/api/orchestrator.service';
@@ -26,6 +25,7 @@ import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
 import { Permission } from '../../../../shared/models/permissions';
 import { DimlessBinaryPipe } from '../../../../shared/pipes/dimless-binary.pipe';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { InventoryDevice } from './inventory-device.model';
 
@@ -72,7 +72,7 @@ export class InventoryDevicesComponent implements OnInit, OnDestroy {
     private authStorageService: AuthStorageService,
     private dimlessBinary: DimlessBinaryPipe,
     private i18n: I18n,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private orchService: OrchestratorService
   ) {}
@@ -184,38 +184,36 @@ export class InventoryDevicesComponent implements OnInit, OnDestroy {
     const hostname = selected.hostname;
     const device = selected.path || selected.device_id;
     this.modalService.show(FormModalComponent, {
-      initialState: {
-        titleText: this.i18n(`Identify device {{device}}`, { device }),
-        message: this.i18n('Please enter the duration how long to blink the LED.'),
-        fields: [
-          {
-            type: 'select',
-            name: 'duration',
-            value: 300,
-            required: true,
-            typeConfig: {
-              options: [
-                { text: this.i18n('1 minute'), value: 60 },
-                { text: this.i18n('2 minutes'), value: 120 },
-                { text: this.i18n('5 minutes'), value: 300 },
-                { text: this.i18n('10 minutes'), value: 600 },
-                { text: this.i18n('15 minutes'), value: 900 }
-              ]
-            }
+      titleText: this.i18n(`Identify device {{device}}`, { device }),
+      message: this.i18n('Please enter the duration how long to blink the LED.'),
+      fields: [
+        {
+          type: 'select',
+          name: 'duration',
+          value: 300,
+          required: true,
+          typeConfig: {
+            options: [
+              { text: this.i18n('1 minute'), value: 60 },
+              { text: this.i18n('2 minutes'), value: 120 },
+              { text: this.i18n('5 minutes'), value: 300 },
+              { text: this.i18n('10 minutes'), value: 600 },
+              { text: this.i18n('15 minutes'), value: 900 }
+            ]
           }
-        ],
-        submitButtonText: this.i18n('Execute'),
-        onSubmit: (values: any) => {
-          this.orchService.identifyDevice(hostname, device, values.duration).subscribe(() => {
-            this.notificationService.show(
-              NotificationType.success,
-              this.i18n(`Identifying '{{device}}' started on host '{{hostname}}'`, {
-                hostname,
-                device
-              })
-            );
-          });
         }
+      ],
+      submitButtonText: this.i18n('Execute'),
+      onSubmit: (values: any) => {
+        this.orchService.identifyDevice(hostname, device, values.duration).subscribe(() => {
+          this.notificationService.show(
+            NotificationType.success,
+            this.i18n(`Identifying '{{device}}' started on host '{{hostname}}'`, {
+              hostname,
+              device
+            })
+          );
+        });
       }
     });
   }
index 1e4b6d989ea5ede88195c04611659f8fe0c025c8..31e2f0581dd5f96fe0c65c5ffabdd2b3ce97212f 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>OSD creation preview</ng-container>
 
@@ -13,7 +13,7 @@
       <div class="modal-footer">
         <cd-submit-button (submitAction)="onSubmit()"
                           [form]="formGroup">{{ action | titlecase }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="activeModal.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index a428903f2ec685e71fd4c979b3d586c9ef9a24c6..6922d99dbbdadaa58777b23fb1fd8cdf346557d9 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
@@ -22,7 +22,7 @@ describe('OsdCreationPreviewModalComponent', () => {
       RouterTestingModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, i18nProviders],
+    providers: [NgbActiveModal, i18nProviders],
     declarations: [OsdCreationPreviewModalComponent]
   });
 
index 37d59f2b3b760fb6a44dd2f7dcb9ed34fcd38603..61b86cad2e7e7d9d42b788d6ef04ebdfb212bce6 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { OsdService } from '../../../../shared/api/osd.service';
 import { ActionLabelsI18n, URLVerbs } from '../../../../shared/constants/app.constants';
@@ -26,7 +26,7 @@ export class OsdCreationPreviewModalComponent {
   formGroup: CdFormGroup;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     public actionLabels: ActionLabelsI18n,
     private formBuilder: CdFormBuilder,
     private osdService: OsdService,
@@ -54,7 +54,7 @@ export class OsdCreationPreviewModalComponent {
         },
         complete: () => {
           this.submitAction.emit();
-          this.bsModalRef.hide();
+          this.activeModal.close();
         }
       });
   }
index 9f21b2dc93d15f4487003339838d2766fd306ad8..8c41b75482a091de2df746eb3940b30bd2906129 100644 (file)
@@ -2,10 +2,10 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angu
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService, ModalOptions } from 'ngx-bootstrap/modal';
 
 import { Icons } from '../../../../shared/enum/icons.enum';
 import { CdTableColumnFiltersChange } from '../../../../shared/models/cd-table-column-filters-change';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { InventoryDevice } from '../../inventory/inventory-devices/inventory-device.model';
 import { OsdDevicesSelectionModalComponent } from '../osd-devices-selection-modal/osd-devices-selection-modal.component';
 import { DevicesSelectionChangeEvent } from './devices-selection-change-event.interface';
@@ -47,7 +47,7 @@ export class OsdDevicesSelectionGroupsComponent implements OnInit, OnChanges {
     addByFilters: this.i18n('Add devices by using filters')
   };
 
-  constructor(private bsModalService: BsModalService, private i18n: I18n) {}
+  constructor(private modalService: ModalService, private i18n: I18n) {}
 
   ngOnInit() {
     this.updateAddButtonTooltip();
@@ -62,17 +62,16 @@ export class OsdDevicesSelectionGroupsComponent implements OnInit, OnChanges {
     if (this.type === 'data') {
       filterColumns = ['hostname', ...filterColumns];
     }
-    const options: ModalOptions = {
-      class: 'modal-xl',
-      initialState: {
-        hostname: this.hostname,
-        deviceType: this.name,
-        devices: this.availDevices,
-        filterColumns: filterColumns
-      }
+    const initialState = {
+      hostname: this.hostname,
+      deviceType: this.name,
+      devices: this.availDevices,
+      filterColumns: filterColumns
     };
-    const modalRef = this.bsModalService.show(OsdDevicesSelectionModalComponent, options);
-    modalRef.content.submitAction.subscribe((result: CdTableColumnFiltersChange) => {
+    const modalRef = this.modalService.show(OsdDevicesSelectionModalComponent, initialState, {
+      size: 'xl'
+    });
+    modalRef.componentInstance.submitAction.subscribe((result: CdTableColumnFiltersChange) => {
       this.devices = result.data;
       this.capacity = _.sumBy(this.devices, 'sys_api.size');
       this.appliedFilters = result.filters;
index 733c207684d9a363a741d41c85f9169ac2c2870d..ce323c7d61aa3f1f0e9c6ddf8ea40dd198a0591b 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>{{ deviceType }} devices</ng-container>
 
@@ -34,7 +34,7 @@
         <cd-submit-button (submitAction)="onSubmit()"
                           [form]="formGroup"
                           [disabled]="!canSubmit || filteredDevices.length === 0">{{ action | titlecase }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="activeModal.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index 0cf0d67ebf41df5f3219590b2f1809b72af9423b..91573a80649d969588ea9a5a4b4e46e6f90daeb8 100644 (file)
@@ -4,7 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
@@ -53,7 +53,7 @@ describe('OsdDevicesSelectionModalComponent', () => {
       RouterTestingModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, i18nProviders],
+    providers: [NgbActiveModal, i18nProviders],
     declarations: [OsdDevicesSelectionModalComponent, InventoryDevicesComponent]
   });
 
index 5fb84e016922866d25cb88b62237b3c1509911b8..deb613a3f0cce44eb406b8c16a0c7aa505253455 100644 (file)
@@ -1,8 +1,8 @@
 import { AfterViewInit, Component, EventEmitter, Output, ViewChild } from '@angular/core';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { TableColumnProp } from '@swimlane/ngx-datatable';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { ActionLabelsI18n } from '../../../../shared/constants/app.constants';
 import { Icons } from '../../../../shared/enum/icons.enum';
@@ -41,7 +41,7 @@ export class OsdDevicesSelectionModalComponent implements AfterViewInit {
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     public actionLabels: ActionLabelsI18n
   ) {
     this.action = actionLabels.ADD;
@@ -82,6 +82,6 @@ export class OsdDevicesSelectionModalComponent implements AfterViewInit {
 
   onSubmit() {
     this.submitAction.emit(this.event);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
index fa4245327988dddde6333e6ce10560f83b87f964..f3094d44501f0bb309507289c255ff439fcd85a9 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Cluster-wide OSD Flags</ng-container>
 
@@ -34,7 +34,7 @@
                           (submitAction)="submitAction()"
                           [form]="osdFlagsForm"
                           i18n>Submit</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index 7470f48566d6cd1a5119f67e5b7f8a170e4eaf03..b73a495af8e19e6a7e17adb6b807297b8cdeb913 100644 (file)
@@ -3,8 +3,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
@@ -28,14 +28,13 @@ describe('OsdFlagsModalComponent', () => {
   configureTestBed({
     imports: [
       ReactiveFormsModule,
-      ModalModule.forRoot(),
       SharedModule,
       HttpClientTestingModule,
       RouterTestingModule,
       ToastrModule.forRoot()
     ],
     declarations: [OsdFlagsModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [i18nProviders, NgbActiveModal]
   });
 
   beforeEach(() => {
@@ -63,7 +62,7 @@ describe('OsdFlagsModalComponent', () => {
   describe('test submitAction', function () {
     let notificationType: NotificationType;
     let notificationService: NotificationService;
-    let bsModalRef: BsModalRef;
+    let bsModalRef: NgbActiveModal;
 
     beforeEach(() => {
       notificationService = TestBed.inject(NotificationService);
@@ -71,8 +70,8 @@ describe('OsdFlagsModalComponent', () => {
         notificationType = type;
       });
 
-      bsModalRef = TestBed.inject(BsModalRef);
-      spyOn(bsModalRef, 'hide').and.callThrough();
+      bsModalRef = TestBed.inject(NgbActiveModal);
+      spyOn(bsModalRef, 'close').and.callThrough();
       component.unknownFlags = ['foo'];
     });
 
@@ -84,7 +83,7 @@ describe('OsdFlagsModalComponent', () => {
       expect(req.request.body).toEqual({ flags: ['pause', 'purged_snapdirs', 'foo'] });
 
       expect(notificationType).toBe(NotificationType.success);
-      expect(component.bsModalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
 
     it('should hide modal if request fails', () => {
@@ -94,7 +93,7 @@ describe('OsdFlagsModalComponent', () => {
       req.flush([], { status: 500, statusText: 'failure' });
 
       expect(notificationService.show).toHaveBeenCalledTimes(0);
-      expect(component.bsModalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
   });
 });
index 12520e41b4e68b8d1b199ce686bfb6a9e841a321..e2cc01a764d0354eb512f658870f414e96db3c08 100644 (file)
@@ -1,9 +1,9 @@
 import { Component, OnInit } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { OsdService } from '../../../../shared/api/osd.service';
 import { NotificationType } from '../../../../shared/enum/notification-type.enum';
@@ -121,7 +121,7 @@ export class OsdFlagsModalComponent implements OnInit {
   unknownFlags: string[] = [];
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private osdService: OsdService,
     private notificationService: NotificationService,
@@ -152,10 +152,10 @@ export class OsdFlagsModalComponent implements OnInit {
     this.osdService.updateFlags(newFlags).subscribe(
       () => {
         this.notificationService.show(NotificationType.success, this.i18n('Updated OSD Flags'));
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
       () => {
-        this.bsModalRef.hide();
+        this.activeModal.close();
       }
     );
   }
index a6ad22f05cb5ae7735f64c3c99add4e4eb247b2b..735680c0b9a02f24129e8af8892e6c080479068d 100644 (file)
@@ -4,7 +4,6 @@ import { Router } from '@angular/router';
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 
 import { OrchestratorService } from '../../../../shared/api/orchestrator.service';
 import { SubmitButtonComponent } from '../../../../shared/components/submit-button/submit-button.component';
@@ -14,6 +13,7 @@ import { CdForm } from '../../../../shared/forms/cd-form';
 import { CdFormGroup } from '../../../../shared/forms/cd-form-group';
 import { CdTableColumn } from '../../../../shared/models/cd-table-column';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { InventoryDevice } from '../../inventory/inventory-devices/inventory-device.model';
 import { OsdCreationPreviewModalComponent } from '../osd-creation-preview-modal/osd-creation-preview-modal.component';
 import { DevicesSelectionChangeEvent } from '../osd-devices-selection-groups/devices-selection-change-event.interface';
@@ -69,7 +69,7 @@ export class OsdFormComponent extends CdForm implements OnInit {
     private i18n: I18n,
     private orchService: OrchestratorService,
     private router: Router,
-    private bsModalService: BsModalService
+    private modalService: ModalService
   ) {
     super();
     this.resource = this.i18n('OSDs');
@@ -208,10 +208,10 @@ export class OsdFormComponent extends CdForm implements OnInit {
     // use user name and timestamp for drive group name
     const user = this.authStorageService.getUsername();
     this.driveGroup.setName(`dashboard-${user}-${_.now()}`);
-    const modalRef = this.bsModalService.show(OsdCreationPreviewModalComponent, {
-      initialState: { driveGroups: [this.driveGroup.spec] }
+    const modalRef = this.modalService.show(OsdCreationPreviewModalComponent, {
+      driveGroups: [this.driveGroup.spec]
     });
-    modalRef.content.submitAction.subscribe(() => {
+    modalRef.componentInstance.submitAction.subscribe(() => {
       this.router.navigate(['/osd']);
     });
     this.previewButton.loading = false;
index ea0db7a3a608a6b065814433fd13f16c19938e4b..44792948d6957ad775fc12edc737210ee0512cf1 100644 (file)
@@ -7,7 +7,6 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { EMPTY, of } from 'rxjs';
 
@@ -27,6 +26,7 @@ import { CdTableAction } from '../../../../shared/models/cd-table-action';
 import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
 import { Permissions } from '../../../../shared/models/permissions';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { CephModule } from '../../../ceph.module';
 import { PerformanceCounterModule } from '../../../performance-counter/performance-counter.module';
 import { OsdReweightModalComponent } from '../osd-reweight-modal/osd-reweight-modal.component';
@@ -107,7 +107,7 @@ describe('OsdListComponent', () => {
     providers: [
       { provide: AuthStorageService, useValue: fakeAuthStorageService },
       TableActionsComponent,
-      BsModalService,
+      ModalService,
       i18nProviders
     ]
   });
@@ -116,7 +116,7 @@ describe('OsdListComponent', () => {
     fixture = TestBed.createComponent(OsdListComponent);
     component = fixture.componentInstance;
     osdService = TestBed.inject(OsdService);
-    modalServiceShowSpy = spyOn(TestBed.inject(BsModalService), 'show').and.stub();
+    modalServiceShowSpy = spyOn(TestBed.inject(ModalService), 'show').and.stub();
   });
 
   it('should create', () => {
@@ -430,7 +430,7 @@ describe('OsdListComponent', () => {
     ): void => {
       const osdServiceSpy = spyOn(osdService, osdServiceMethodName).and.callFake(() => EMPTY);
       openActionModal(actionName);
-      const initialState = modalServiceShowSpy.calls.first().args[1].initialState;
+      const initialState = modalServiceShowSpy.calls.first().args[1];
       const submit = initialState.onSubmit || initialState.submitAction;
       submit.call(component);
 
index ed0f1cdd7e04576ab101fcf5e0fe0ff150c426a7..67224ce68718bf46d643e882c7e04845eed24391 100644 (file)
@@ -2,9 +2,9 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 import { FormControl } from '@angular/forms';
 import { Router } from '@angular/router';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin, Observable } from 'rxjs';
 
 import { OsdService } from '../../../../shared/api/osd.service';
@@ -26,6 +26,7 @@ import { Permissions } from '../../../../shared/models/permissions';
 import { DimlessBinaryPipe } from '../../../../shared/pipes/dimless-binary.pipe';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
 import { DepCheckerService } from '../../../../shared/services/dep-checker.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { TaskWrapperService } from '../../../../shared/services/task-wrapper.service';
 import { URLBuilderService } from '../../../../shared/services/url-builder.service';
@@ -61,7 +62,7 @@ export class OsdListComponent extends ListWithDetails implements OnInit {
 
   permissions: Permissions;
   tableActions: CdTableAction[];
-  bsModalRef: BsModalRef;
+  bsModalRef: NgbModalRef;
   columns: CdTableColumn[];
   clusterWideActions: CdTableAction[];
   icons = Icons;
@@ -85,7 +86,7 @@ export class OsdListComponent extends ListWithDetails implements OnInit {
     private authStorageService: AuthStorageService,
     private osdService: OsdService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     private router: Router,
@@ -378,31 +379,29 @@ export class OsdListComponent extends ListWithDetails implements OnInit {
     const selectedOsd = _.filter(this.osds, ['id', this.selection.first().id]).pop();
 
     this.modalService.show(FormModalComponent, {
-      initialState: {
-        titleText: this.i18n('Edit OSD: {{id}}', {
-          id: selectedOsd.id
-        }),
-        fields: [
-          {
-            type: 'text',
-            name: 'deviceClass',
-            value: selectedOsd.tree.device_class,
-            label: this.i18n('Device class'),
-            required: true
-          }
-        ],
-        submitButtonText: this.i18n('Edit OSD'),
-        onSubmit: (values: any) => {
-          this.osdService.update(selectedOsd.id, values.deviceClass).subscribe(() => {
-            this.notificationService.show(
-              NotificationType.success,
-              this.i18n(`Updated OSD '{{id}}'`, {
-                id: selectedOsd.id
-              })
-            );
-            this.getOsdList();
-          });
+      titleText: this.i18n('Edit OSD: {{id}}', {
+        id: selectedOsd.id
+      }),
+      fields: [
+        {
+          type: 'text',
+          name: 'deviceClass',
+          value: selectedOsd.tree.device_class,
+          label: this.i18n('Device class'),
+          required: true
         }
+      ],
+      submitButtonText: this.i18n('Edit OSD'),
+      onSubmit: (values: any) => {
+        this.osdService.update(selectedOsd.id, values.deviceClass).subscribe(() => {
+          this.notificationService.show(
+            NotificationType.success,
+            this.i18n(`Updated OSD '{{id}}'`, {
+              id: selectedOsd.id
+            })
+          );
+          this.getOsdList();
+        });
       }
     });
   }
@@ -417,38 +416,34 @@ export class OsdListComponent extends ListWithDetails implements OnInit {
       deep: deep
     };
 
-    this.bsModalRef = this.modalService.show(OsdScrubModalComponent, { initialState });
+    this.bsModalRef = this.modalService.show(OsdScrubModalComponent, initialState);
   }
 
   configureFlagsAction() {
-    this.bsModalRef = this.modalService.show(OsdFlagsModalComponent, {});
+    this.bsModalRef = this.modalService.show(OsdFlagsModalComponent);
   }
 
   showConfirmationModal(markAction: string, onSubmit: (id: number) => Observable<any>) {
     this.bsModalRef = this.modalService.show(ConfirmationModalComponent, {
-      initialState: {
-        titleText: this.i18n('Mark OSD {{markAction}}', { markAction: markAction }),
-        buttonText: this.i18n('Mark {{markAction}}', { markAction: markAction }),
-        bodyTpl: this.markOsdConfirmationTpl,
-        bodyContext: {
-          markActionDescription: markAction
-        },
-        onSubmit: () => {
-          observableForkJoin(
-            this.getSelectedOsdIds().map((osd: any) => onSubmit.call(this.osdService, osd))
-          ).subscribe(() => this.bsModalRef.hide());
-        }
+      titleText: this.i18n('Mark OSD {{markAction}}', { markAction: markAction }),
+      buttonText: this.i18n('Mark {{markAction}}', { markAction: markAction }),
+      bodyTpl: this.markOsdConfirmationTpl,
+      bodyContext: {
+        markActionDescription: markAction
+      },
+      onSubmit: () => {
+        observableForkJoin(
+          this.getSelectedOsdIds().map((osd: any) => onSubmit.call(this.osdService, osd))
+        ).subscribe(() => this.bsModalRef.close());
       }
     });
   }
 
   reweight() {
     const selectedOsd = this.osds.filter((o) => o.id === this.selection.first().id).pop();
-    this.modalService.show(OsdReweightModalComponent, {
-      initialState: {
-        currentWeight: selectedOsd.weight,
-        osdId: selectedOsd.id
-      }
+    this.bsModalRef = this.modalService.show(OsdReweightModalComponent, {
+      currentWeight: selectedOsd.weight,
+      osdId: selectedOsd.id
     });
   }
 
@@ -511,39 +506,37 @@ export class OsdListComponent extends ListWithDetails implements OnInit {
   ): void {
     check(this.getSelectedOsdIds()).subscribe((result) => {
       const modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-        initialState: {
-          actionDescription: actionDescription,
-          itemDescription: itemDescription,
-          bodyTemplate: this.criticalConfirmationTpl,
-          bodyContext: {
-            safeToPerform: result[checkKey],
-            message: result.message,
-            actionDescription: templateItemDescription,
-            osdIds: this.getSelectedOsdIds()
-          },
-          childFormGroup: childFormGroup,
-          childFormGroupTemplate: childFormGroupTemplate,
-          submitAction: () => {
-            const observable = observableForkJoin(
-              this.getSelectedOsdIds().map((osd: any) => action.call(this.osdService, osd))
+        actionDescription: actionDescription,
+        itemDescription: itemDescription,
+        bodyTemplate: this.criticalConfirmationTpl,
+        bodyContext: {
+          safeToPerform: result[checkKey],
+          message: result.message,
+          actionDescription: templateItemDescription,
+          osdIds: this.getSelectedOsdIds()
+        },
+        childFormGroup: childFormGroup,
+        childFormGroupTemplate: childFormGroupTemplate,
+        submitAction: () => {
+          const observable = observableForkJoin(
+            this.getSelectedOsdIds().map((osd: any) => action.call(this.osdService, osd))
+          );
+          if (taskWrapped) {
+            observable.subscribe({
+              error: () => {
+                this.getOsdList();
+                modalRef.close();
+              },
+              complete: () => modalRef.close()
+            });
+          } else {
+            observable.subscribe(
+              () => {
+                this.getOsdList();
+                modalRef.close();
+              },
+              () => modalRef.close()
             );
-            if (taskWrapped) {
-              observable.subscribe({
-                error: () => {
-                  this.getOsdList();
-                  modalRef.hide();
-                },
-                complete: () => modalRef.hide()
-              });
-            } else {
-              observable.subscribe(
-                () => {
-                  this.getOsdList();
-                  modalRef.hide();
-                },
-                () => modalRef.hide()
-              );
-            }
           }
         }
       });
@@ -551,10 +544,10 @@ export class OsdListComponent extends ListWithDetails implements OnInit {
   }
 
   configureQosParamsAction() {
-    this.bsModalRef = this.modalService.show(OsdRecvSpeedModalComponent, {});
+    this.bsModalRef = this.modalService.show(OsdRecvSpeedModalComponent);
   }
 
   configurePgScrubAction() {
-    this.bsModalRef = this.modalService.show(OsdPgScrubModalComponent, { class: 'modal-lg' });
+    this.bsModalRef = this.modalService.show(OsdPgScrubModalComponent, { size: 'lg' });
   }
 }
index a0216f72a23fc42290c16f532033be62e7b3dae1..4568650ae6b5bebec8949e9f7cb2f780b72db35f 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n="form title|Example: Create Pool@@formTitle"
                 class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
 
@@ -37,7 +37,7 @@
                           (submitAction)="submitAction()"
                           i18n="form action button|Example: Create Pool@@formActionButton"
                           [form]="osdPgScrubForm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide">
+        <cd-back-button [back]="activeModal.close">
         </cd-back-button>
       </div>
     </form>
index f5c7ddd237159f28ff6fbe12f18095a9bc99cdf2..083398d1ce06f0c59726fe355b772bab81454f9b 100644 (file)
@@ -4,7 +4,7 @@ import { ReactiveFormsModule } from '@angular/forms';
 import { Router } from '@angular/router';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 import { of as observableOf } from 'rxjs';
 
@@ -23,14 +23,13 @@ describe('OsdPgScrubModalComponent', () => {
   configureTestBed({
     imports: [
       HttpClientTestingModule,
-      ModalModule.forRoot(),
       ReactiveFormsModule,
       RouterTestingModule,
       SharedModule,
       ToastrModule.forRoot()
     ],
     declarations: [OsdPgScrubModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index 410f53f7a071b6dcc3a26dbe150e6d5a62e8af5f..e2b4c1d4450078e93726c5fbe5f4eca8dc18e0f7 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, ViewChild } from '@angular/core';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin } from 'rxjs';
 
 import { ConfigOptionComponent } from '../../../../shared/components/config-option/config-option.component';
@@ -35,7 +35,7 @@ export class OsdPgScrubModalComponent {
   advancedEnabled = false;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private notificationService: NotificationService,
     private i18n: I18n,
@@ -60,10 +60,10 @@ export class OsdPgScrubModalComponent {
           NotificationType.success,
           this.i18n('Updated PG scrub options')
         );
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
       () => {
-        this.bsModalRef.hide();
+        this.activeModal.close();
       }
     );
   }
index 26fb412c686c64989f68e1d850d7883214ea487d..0bc4fef593433879aa48644e6b70c573761a93fc 100755 (executable)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>OSD Recovery Priority</ng-container>
 
@@ -85,7 +85,7 @@
                           (submitAction)="submitAction()"
                           [form]="osdRecvSpeedForm"
                           i18n>Submit</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index d050b5932ca1ce1667df0c675aef3f7678e49047..5c08024a86b695cd8549106c3421d0a6b07a3402 100755 (executable)
@@ -3,8 +3,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of as observableOf } from 'rxjs';
 
@@ -21,14 +21,13 @@ describe('OsdRecvSpeedModalComponent', () => {
   configureTestBed({
     imports: [
       HttpClientTestingModule,
-      ModalModule.forRoot(),
       ReactiveFormsModule,
       RouterTestingModule,
       SharedModule,
       ToastrModule.forRoot()
     ],
     declarations: [OsdRecvSpeedModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   let configOptions: any[] = [];
index eaaa70a4bc356851b4dbdfb73a730b7b4249c9bf..4eaffd27fbcdf59d42d1deb777f245d22f899738 100755 (executable)
@@ -1,9 +1,9 @@
 import { Component, OnInit } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { ConfigurationService } from '../../../../shared/api/configuration.service';
 import { OsdService } from '../../../../shared/api/osd.service';
@@ -27,7 +27,7 @@ export class OsdRecvSpeedModalComponent implements OnInit {
   priorityAttrs = {};
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private configService: ConfigurationService,
     private notificationService: NotificationService,
@@ -228,10 +228,10 @@ export class OsdRecvSpeedModalComponent implements OnInit {
             value: this.osdRecvSpeedForm.getValue('priority')
           })
         );
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
       () => {
-        this.bsModalRef.hide();
+        this.activeModal.close();
       }
     );
   }
index 7760dd09680caddf7ed04f99d4a304e929376cb5..9e67bbb6e1be28a17cfdd026badfd336c65a83a7 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Reweight OSD: {{ osdId }}</ng-container>
 
@@ -33,7 +33,7 @@
                           [form]="reweightForm"
                           [disabled]="reweightForm.invalid"
                           i18n>Reweight</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index e59f360340adc211119b338d1beba242a468042d..7b98b6d0340dfbe5ea0bd570a597ab461b129294 100644 (file)
@@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { of } from 'rxjs';
 
 import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
@@ -26,7 +26,7 @@ describe('OsdReweightModalComponent', () => {
       SubmitButtonComponent,
       BackButtonComponent
     ],
-    providers: [OsdService, BsModalRef, CdFormBuilder, i18nProviders]
+    providers: [OsdService, NgbActiveModal, CdFormBuilder, i18nProviders]
   });
 
   beforeEach(() => {
index 4f884d1bdef4c7635265bac0ef64e4aa5443acb7..fad56e284c5b9969366b7222ee3cd66e8454b235 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 import { Validators } from '@angular/forms';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { OsdService } from '../../../../shared/api/osd.service';
 import { CdFormBuilder } from '../../../../shared/forms/cd-form-builder';
@@ -18,7 +18,7 @@ export class OsdReweightModalComponent implements OnInit {
   reweightForm: CdFormGroup;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private osdService: OsdService,
     private fb: CdFormBuilder
   ) {}
@@ -40,6 +40,6 @@ export class OsdReweightModalComponent implements OnInit {
   reweight() {
     this.osdService
       .reweight(this.osdId, this.reweightForm.value.weight)
-      .subscribe(() => this.bsModalRef.hide());
+      .subscribe(() => this.activeModal.close());
   }
 }
index f5a5bb2f1ced3423c1e081276525315e0487d282..c82063b3c09c4ffad99c436aed0167e37a618c05 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>OSDs {deep, select, 1 {Deep }}Scrub</ng-container>
 
@@ -16,7 +16,7 @@
         <cd-submit-button (submitAction)="scrub()"
                           [form]="scrubForm"
                           i18n>Submit</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index a32e173678c91472b3a5f40c604b4ec75bd1ba3b..a20df3bb3a24420f387c5172be6825abb3e0bc04 100644 (file)
@@ -2,7 +2,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper';
 import { OsdService } from '../../../../shared/api/osd.service';
@@ -31,7 +31,7 @@ describe('OsdScrubModalComponent', () => {
     declarations: [OsdScrubModalComponent, JoinPipe],
     schemas: [NO_ERRORS_SCHEMA],
     providers: [
-      BsModalRef,
+      NgbActiveModal,
       JoinPipe,
       { provide: OsdService, useValue: fakeService },
       { provide: NotificationService, useValue: fakeService },
index c19e523744527e3e542c9e463914c513c5df80a3..c23fb500537462630e744c7d7389347fc6b82360 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { forkJoin } from 'rxjs';
 
 import { OsdService } from '../../../../shared/api/osd.service';
@@ -21,7 +21,7 @@ export class OsdScrubModalComponent implements OnInit {
   selected: any[] = [];
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private osdService: OsdService,
     private notificationService: NotificationService,
     private i18n: I18n,
@@ -45,9 +45,9 @@ export class OsdScrubModalComponent implements OnInit {
           })
         );
 
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
-      () => this.bsModalRef.hide()
+      () => this.activeModal.close()
     );
   }
 }
index b331140d655dcb550cee513b1171324a7b604210..0c5b6b05902b4e391dbcac6dd8676cf1f656d5af 100644 (file)
@@ -8,7 +8,6 @@ import { RouterTestingModule } from '@angular/router/testing';
 import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
 import { BsDatepickerDirective, BsDatepickerModule } from 'ngx-bootstrap/datepicker';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of, throwError } from 'rxjs';
 
@@ -26,6 +25,7 @@ import { CdFormGroup } from '../../../../shared/forms/cd-form-group';
 import { AlertmanagerSilence } from '../../../../shared/models/alertmanager-silence';
 import { Permission } from '../../../../shared/models/permissions';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { SharedModule } from '../../../../shared/shared.module';
 import { SilenceFormComponent } from './silence-form.component';
@@ -460,10 +460,10 @@ describe('SilenceFormComponent', () => {
       addMatcher('alertname', 'alert.*', true);
       expectMatch(null);
 
-      const modalService = TestBed.inject(BsModalService);
+      const modalService = TestBed.inject(ModalService);
       spyOn(modalService, 'show').and.callFake(() => {
         return {
-          content: {
+          componentInstance: {
             preFillControls: (matcher: any) => {
               expect(matcher).toBe(component.matchers[0]);
             },
index 4f36ef92ad8f57f38ac85652e3d1bfcafc8f8a2e..0449a8e048dea704055ccce800f3d94cb5415dbb 100644 (file)
@@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router';
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 
 import { PrometheusService } from '../../../../shared/api/prometheus.service';
 import {
@@ -24,6 +23,7 @@ import {
 import { Permission } from '../../../../shared/models/permissions';
 import { AlertmanagerAlert, PrometheusRule } from '../../../../shared/models/prometheus-alerts';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { PrometheusSilenceMatcherService } from '../../../../shared/services/prometheus-silence-matcher.service';
 import { TimeDiffService } from '../../../../shared/services/time-diff.service';
@@ -79,7 +79,7 @@ export class SilenceFormComponent {
     private notificationService: NotificationService,
     private route: ActivatedRoute,
     private timeDiff: TimeDiffService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private silenceMatcher: PrometheusSilenceMatcherService,
     private actionLabels: ActionLabelsI18n,
     private succeededLabels: SucceededActionLabelsI18n
@@ -271,14 +271,14 @@ export class SilenceFormComponent {
   }
 
   showMatcherModal(index?: number) {
-    const modalRef = this.bsModalService.show(SilenceMatcherModalComponent);
-    const modal = modalRef.content as SilenceMatcherModalComponent;
-    modal.rules = this.rules;
+    const modalRef = this.modalService.show(SilenceMatcherModalComponent);
+    const modalComponent = modalRef.componentInstance as SilenceMatcherModalComponent;
+    modalComponent.rules = this.rules;
     if (_.isNumber(index)) {
-      modal.editMode = true;
-      modal.preFillControls(this.matchers[index]);
+      modalComponent.editMode = true;
+      modalComponent.preFillControls(this.matchers[index]);
     }
-    modalRef.content.submitAction.subscribe((matcher: AlertmanagerSilenceMatcher) => {
+    modalComponent.submitAction.subscribe((matcher: AlertmanagerSilenceMatcher) => {
       this.setMatcher(matcher, index);
     });
   }
index 088202764fe085d57bc0b39d61cc2b013f741f5b..859b94b5d3e6307f2c4f3293f6c98271822f342c 100644 (file)
@@ -3,7 +3,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -16,6 +15,7 @@ import { PrometheusService } from '../../../../shared/api/prometheus.service';
 import { CriticalConfirmationModalComponent } from '../../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
 import { TableActionsComponent } from '../../../../shared/datatable/table-actions/table-actions.component';
 import { NotificationType } from '../../../../shared/enum/notification-type.enum';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { SharedModule } from '../../../../shared/shared.module';
 import { SilenceListComponent } from './silence-list.component';
@@ -29,7 +29,6 @@ describe('SilenceListComponent', () => {
     imports: [
       BrowserAnimationsModule,
       SharedModule,
-      ModalModule.forRoot(),
       ToastrModule.forRoot(),
       RouterTestingModule,
       HttpClientTestingModule
@@ -97,8 +96,8 @@ describe('SilenceListComponent', () => {
 
     const expireSilence = () => {
       component.expireSilence();
-      const deletion: CriticalConfirmationModalComponent = component.modalRef.content;
-      deletion.modalRef = new BsModalRef();
+      const deletion: CriticalConfirmationModalComponent = component.modalRef.componentInstance;
+      // deletion.modalRef = new BsModalRef();
       deletion.ngOnInit();
       deletion.callSubmitAction();
     };
@@ -113,9 +112,9 @@ describe('SilenceListComponent', () => {
       const mockObservable = () => of([]);
       spyOn(component, 'refresh').and.callFake(mockObservable);
       spyOn(prometheusService, 'expireSilence').and.callFake(mockObservable);
-      spyOn(TestBed.inject(BsModalService), 'show').and.callFake((deletionClass, config) => {
+      spyOn(TestBed.inject(ModalService), 'show').and.callFake((deletionClass, config) => {
         return {
-          content: Object.assign(new deletionClass(), config.initialState)
+          componentInstance: Object.assign(new deletionClass(), config)
         };
       });
     });
index d2b36f6af75498d791d53d80301f244d1f2794ef..64bb72b8df0e2d145b80072e9e630071d5415923 100644 (file)
@@ -1,8 +1,8 @@
 import { Component } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import { SortDirection, SortPropDir } from '@swimlane/ngx-datatable';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { Observable, Subscriber } from 'rxjs';
 
 import { PrometheusService } from '../../../../shared/api/prometheus.service';
@@ -22,6 +22,7 @@ import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
 import { Permission } from '../../../../shared/models/permissions';
 import { CdDatePipe } from '../../../../shared/pipes/cd-date.pipe';
 import { AuthStorageService } from '../../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../../shared/services/modal.service';
 import { NotificationService } from '../../../../shared/services/notification.service';
 import { URLBuilderService } from '../../../../shared/services/url-builder.service';
 
@@ -39,7 +40,7 @@ export class SilenceListComponent extends ListWithDetails {
   tableActions: CdTableAction[];
   permission: Permission;
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   customCss = {
     'badge badge-danger': 'active',
     'badge badge-warning': 'pending',
@@ -52,7 +53,7 @@ export class SilenceListComponent extends ListWithDetails {
     private i18n: I18n,
     private cdDatePipe: CdDatePipe,
     private prometheusService: PrometheusService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private urlBuilder: URLBuilderService,
     private actionLabels: ActionLabelsI18n,
@@ -168,33 +169,31 @@ export class SilenceListComponent extends ListWithDetails {
     const i18nSilence = this.i18n('Silence');
     const applicationName = 'Prometheus';
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: i18nSilence,
-        itemNames: [id],
-        actionDescription: this.actionLabels.EXPIRE,
-        submitActionObservable: () =>
-          new Observable((observer: Subscriber<any>) => {
-            this.prometheusService.expireSilence(id).subscribe(
-              () => {
-                this.notificationService.show(
-                  NotificationType.success,
-                  `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`,
-                  undefined,
-                  undefined,
-                  applicationName
-                );
-              },
-              (resp) => {
-                resp['application'] = applicationName;
-                observer.error(resp);
-              },
-              () => {
-                observer.complete();
-                this.refresh();
-              }
-            );
-          })
-      }
+      itemDescription: i18nSilence,
+      itemNames: [id],
+      actionDescription: this.actionLabels.EXPIRE,
+      submitActionObservable: () =>
+        new Observable((observer: Subscriber<any>) => {
+          this.prometheusService.expireSilence(id).subscribe(
+            () => {
+              this.notificationService.show(
+                NotificationType.success,
+                `${this.succeededLabels.EXPIRED} ${i18nSilence} ${id}`,
+                undefined,
+                undefined,
+                applicationName
+              );
+            },
+            (resp) => {
+              resp['application'] = applicationName;
+              observer.error(resp);
+            },
+            () => {
+              observer.complete();
+              this.refresh();
+            }
+          );
+        })
     });
   }
 }
index 9285f3ff2b1d3b44cdbd89bdea54beac1e0c7e1b..853b24520d20d6a1b3083cc708a6c11bc993016c 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Matcher</ng-container>
 
@@ -77,7 +77,7 @@
                           [form]="form">
           <ng-container i18n>{editMode, select, 1 {Update} other {Add}}</ng-container>
         </cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Close"
                         i18n-name>
         </cd-back-button>
index 112626ff6e928788889cadba18ed1089b3f08699..dc8117809635ba32dae3c46df224de0de55d46aa 100644 (file)
@@ -3,8 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
 
 import {
   configureTestBed,
@@ -33,7 +32,7 @@ describe('SilenceMatcherModalComponent', () => {
       RouterTestingModule,
       ReactiveFormsModule
     ],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index 9621b4acaa67cb09c57171e85d21c5a8774f312e..cef04ef55595ef3398f0bbf3b59f8ae30cbebbb7 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, EventEmitter, Output } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { Observable } from 'rxjs';
 import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators';
 
@@ -34,7 +34,7 @@ export class SilenceMatcherModalComponent {
   constructor(
     private formBuilder: CdFormBuilder,
     private silenceMatcher: PrometheusSilenceMatcherService,
-    public bsModalRef: BsModalRef
+    public activeModal: NgbActiveModal
   ) {
     this.createForm();
     this.subscribeToChanges();
@@ -76,7 +76,7 @@ export class SilenceMatcherModalComponent {
 
   onSubmit() {
     this.submitAction.emit(this.form.value);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 
   search = (text$: Observable<string>) => {
index 616c8ef7a347a887f476350160c4461d5fb7c5da..cf3994f0cac083f277be54157264010e5c82e4a1 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { Subscription } from 'rxjs';
 
 import { NfsService } from '../../../shared/api/nfs.service';
@@ -20,6 +20,7 @@ import { FinishedTask } from '../../../shared/models/finished-task';
 import { Permission } from '../../../shared/models/permissions';
 import { Task } from '../../../shared/models/task';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 
@@ -47,7 +48,7 @@ export class NfsListComponent extends ListWithDetails implements OnInit, OnDestr
   tableActions: CdTableAction[];
   isDefaultCluster = false;
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   builders = {
     'nfs/create': (metadata: any) => {
@@ -62,7 +63,7 @@ export class NfsListComponent extends ListWithDetails implements OnInit, OnDestr
   constructor(
     private authStorageService: AuthStorageService,
     private i18n: I18n,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private nfsService: NfsService,
     private taskListService: TaskListService,
     private taskWrapper: TaskWrapperService,
@@ -208,18 +209,16 @@ export class NfsListComponent extends ListWithDetails implements OnInit, OnDestr
     const export_id = this.selection.first().export_id;
 
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: this.i18n('NFS export'),
-        itemNames: [`${cluster_id}:${export_id}`],
-        submitActionObservable: () =>
-          this.taskWrapper.wrapTaskAroundCall({
-            task: new FinishedTask('nfs/delete', {
-              cluster_id: cluster_id,
-              export_id: export_id
-            }),
-            call: this.nfsService.delete(cluster_id, export_id)
-          })
-      }
+      itemDescription: this.i18n('NFS export'),
+      itemNames: [`${cluster_id}:${export_id}`],
+      submitActionObservable: () =>
+        this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask('nfs/delete', {
+            cluster_id: cluster_id,
+            export_id: export_id
+          }),
+          call: this.nfsService.delete(cluster_id, export_id)
+        })
     });
   }
 }
index 073b6e40f0af9bfaf9ce3830dba44be12be1f171..546a5ec437ab98e4c14ca483806fc7282cf8a501 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n="form title|Example: Create Pool@@formTitle"
                 class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
 
         <cd-submit-button (submitAction)="onSubmit()"
                           i18n="form action button|Example: Create Pool@@formActionButton"
                           [form]="frm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="activeModal.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index 36696479d9bb6ef13f954619fedffc8a1d213b53..62bdbebc367ba9e62065b5262b204b49112dd7d8 100644 (file)
@@ -2,8 +2,8 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -79,7 +79,7 @@ describe('CrushRuleFormComponent', () => {
       PoolModule,
       NgBootstrapFormValidationModule.forRoot()
     ],
-    providers: [CrushRuleService, BsModalRef, i18nProviders]
+    providers: [CrushRuleService, NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index 37324979bf9e68e1f95427f33e730c97a6ecd02e..dcf60e4cd88bceeb2a568e3e286d999740230771 100644 (file)
@@ -1,9 +1,9 @@
 import { Component, EventEmitter, OnInit, Output } from '@angular/core';
 import { Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { CrushRuleService } from '../../../shared/api/crush-rule.service';
 import { CrushNodeSelectionClass } from '../../../shared/classes/crush.node.selection.class';
@@ -33,7 +33,7 @@ export class CrushRuleFormModalComponent extends CrushNodeSelectionClass impleme
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private taskWrapper: TaskWrapperService,
     private crushRuleService: CrushRuleService,
     private i18n: I18n,
@@ -102,7 +102,7 @@ export class CrushRuleFormModalComponent extends CrushNodeSelectionClass impleme
           this.form.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.bsModalRef.hide();
+          this.activeModal.close();
           this.submitAction.emit(rule);
         }
       });
index cbdeb36b1b4a475595fdd09c917d20f8d79f93c3..1c98e1aaf91edea2085949914ce3d2a3edf2f965 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n="form title|Example: Create Pool@@formTitle"
                 class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
 
         <cd-submit-button (submitAction)="onSubmit()"
                           i18n="form action button|Example: Create Pool@@formActionButton"
                           [form]="frm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="activeModal.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index 6ce5e83bf09961948018fc3632b581050a3ea640..7499a3148cd6c671e4b2173ada78492a5df88b66 100644 (file)
@@ -3,8 +3,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { By } from '@angular/platform-browser';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -37,7 +37,7 @@ describe('ErasureCodeProfileFormModalComponent', () => {
       PoolModule,
       NgBootstrapFormValidationModule.forRoot()
     ],
-    providers: [ErasureCodeProfileService, BsModalRef, i18nProviders]
+    providers: [ErasureCodeProfileService, NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index 298ceaff36d93299a199d4ce62e8292d7394124e..814b1696fe0c3f89404c47b43ff7dc2880a06cc4 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, EventEmitter, OnInit, Output } from '@angular/core';
 import { Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { ErasureCodeProfileService } from '../../../shared/api/erasure-code-profile.service';
 import { CrushNodeSelectionClass } from '../../../shared/classes/crush.node.selection.class';
@@ -45,7 +45,7 @@ export class ErasureCodeProfileFormModalComponent extends CrushNodeSelectionClas
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private taskWrapper: TaskWrapperService,
     private ecpService: ErasureCodeProfileService,
     private i18n: I18n,
@@ -324,7 +324,7 @@ export class ErasureCodeProfileFormModalComponent extends CrushNodeSelectionClas
           this.form.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.bsModalRef.hide();
+          this.activeModal.close();
           this.submitAction.emit(profile);
         }
       });
index eab97750c6c4f6606c5f85d82099e803f1feac4e..af8999a807c10bf4678b8a1ba0ad6a83e632d41c 100644 (file)
@@ -6,10 +6,14 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { ActivatedRoute, Router, Routes } from '@angular/router';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
+import {
+  NgbActiveModal,
+  NgbModalModule,
+  NgbModalRef,
+  NgbNavModule
+} from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -32,6 +36,7 @@ import { ErasureCodeProfile } from '../../../shared/models/erasure-code-profile'
 import { Permission } from '../../../shared/models/permissions';
 import { PoolFormInfo } from '../../../shared/models/pool-form-info';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { Pool } from '../pool';
 import { PoolModule } from '../pool.module';
@@ -130,25 +135,29 @@ describe('PoolFormComponent', () => {
 
   const routes: Routes = [{ path: '404', component: NotFoundComponent }];
 
-  configureTestBed({
-    declarations: [NotFoundComponent],
-    imports: [
-      BrowserAnimationsModule,
-      HttpClientTestingModule,
-      RouterTestingModule.withRoutes(routes),
-      ToastrModule.forRoot(),
-      NgbNavModule,
-      PoolModule,
-      NgBootstrapFormValidationModule.forRoot()
-    ],
-    providers: [
-      ErasureCodeProfileService,
-      BsModalRef,
-      SelectBadgesComponent,
-      { provide: ActivatedRoute, useValue: { params: of({ name: 'somePoolName' }) } },
-      i18nProviders
-    ]
-  });
+  configureTestBed(
+    {
+      declarations: [NotFoundComponent],
+      imports: [
+        BrowserAnimationsModule,
+        HttpClientTestingModule,
+        RouterTestingModule.withRoutes(routes),
+        ToastrModule.forRoot(),
+        NgbNavModule,
+        PoolModule,
+        NgBootstrapFormValidationModule.forRoot(),
+        NgbModalModule
+      ],
+      providers: [
+        ErasureCodeProfileService,
+        NgbActiveModal,
+        SelectBadgesComponent,
+        { provide: ActivatedRoute, useValue: { params: of({ name: 'somePoolName' }) } },
+        i18nProviders
+      ]
+    },
+    [CriticalConfirmationModalComponent]
+  );
 
   let navigationSpy: jasmine.Spy;
 
@@ -782,9 +791,9 @@ describe('PoolFormComponent', () => {
     it('should select the newly created rule', () => {
       expect(form.getValue('crushRule').rule_name).toBe('rep1');
       const name = 'awesomeRule';
-      spyOn(TestBed.inject(BsModalService), 'show').and.callFake(() => {
+      spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => {
         return {
-          content: {
+          componentInstance: {
             submitAction: of({ name })
           }
         };
@@ -845,11 +854,11 @@ describe('PoolFormComponent', () => {
       };
 
       beforeEach(() => {
-        modalSpy = spyOn(TestBed.inject(BsModalService), 'show').and.callFake(
-          (deletionClass: any, config: any) => {
-            deletion = Object.assign(new deletionClass(), config.initialState);
+        modalSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake(
+          (deletionClass: any, initialState: any) => {
+            deletion = Object.assign(new deletionClass(), initialState);
             return {
-              content: deletion
+              componentInstance: deletion
             };
           }
         );
@@ -906,7 +915,7 @@ describe('PoolFormComponent', () => {
 
         it('should hide the tooltip when clicking on add', () => {
           modalSpy.and.callFake((): any => ({
-            content: {
+            componentInstance: {
               submitAction: of('someRule')
             }
           }));
@@ -950,9 +959,9 @@ describe('PoolFormComponent', () => {
       spyOn(ecpService, 'list').and.callFake(() => of(infoReturn.erasure_code_profiles));
       expect(form.getValue('erasureProfile').name).toBe('ecp1');
       const name = 'awesomeProfile';
-      spyOn(TestBed.inject(BsModalService), 'show').and.callFake(() => {
+      spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => {
         return {
-          content: {
+          componentInstance: {
             submitAction: of({ name })
           }
         };
@@ -969,11 +978,11 @@ describe('PoolFormComponent', () => {
       let deletion: CriticalConfirmationModalComponent;
       let deleteSpy: jasmine.Spy;
       let modalSpy: jasmine.Spy;
-      let modal: any;
+      let modal: NgbModalRef;
 
       const callEcpDeletion = () => {
         component.deleteErasureCodeProfile();
-        modal.ref.content.callSubmitAction();
+        modal.componentInstance.callSubmitAction();
       };
 
       const expectSuccessfulEcpDeletion = (name: string) => {
@@ -994,10 +1003,10 @@ describe('PoolFormComponent', () => {
 
       beforeEach(() => {
         deletion = undefined;
-        modalSpy = spyOn(TestBed.inject(BsModalService), 'show').and.callFake(
+        modalSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake(
           (comp: any, init: any) => {
             modal = modalServiceShow(comp, init);
-            return modal.ref;
+            return modal;
           }
         );
         deleteSpy = spyOn(ecpService, 'delete').and.callFake((name: string) => {
@@ -1066,7 +1075,7 @@ describe('PoolFormComponent', () => {
 
         it('should hide the tooltip when clicking on add', () => {
           modalSpy.and.callFake((): any => ({
-            content: {
+            componentInstance: {
               submitAction: of('someProfile')
             }
           }));
index 1685f727b096e4fcf0333a6d2e2e857255c491b0..f57b70a1231cbd912a02feeb52ee280e758faa4e 100644 (file)
@@ -5,7 +5,6 @@ import { ActivatedRoute, Router } from '@angular/router';
 import { NgbNav, NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { Observable, Subscription } from 'rxjs';
 
 import { CrushRuleService } from '../../../shared/api/crush-rule.service';
@@ -32,6 +31,7 @@ import { PoolFormInfo } from '../../../shared/models/pool-form-info';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
 import { FormatterService } from '../../../shared/services/formatter.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { CrushRuleFormModalComponent } from '../crush-rule-form-modal/crush-rule-form-modal.component';
 import { ErasureCodeProfileFormModalComponent } from '../erasure-code-profile-form/erasure-code-profile-form-modal.component';
@@ -89,11 +89,10 @@ export class PoolFormComponent extends CdForm implements OnInit {
     private dimlessBinaryPipe: DimlessBinaryPipe,
     private route: ActivatedRoute,
     private router: Router,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private poolService: PoolService,
     private authStorageService: AuthStorageService,
     private formatter: FormatterService,
-    private bsModalService: BsModalService,
     private taskWrapper: TaskWrapperService,
     private ecpService: ErasureCodeProfileService,
     private crushRuleService: CrushRuleService,
@@ -574,8 +573,8 @@ export class PoolFormComponent extends CdForm implements OnInit {
 
   private addModal(modalComponent: Type<any>, reload: (name: string) => void) {
     this.hideOpenTooltips();
-    const modalRef = this.bsModalService.show(modalComponent);
-    modalRef.content.submitAction.subscribe((item: any) => {
+    const modalRef = this.modalService.show(modalComponent);
+    modalRef.componentInstance.submitAction.subscribe((item: any) => {
       reload(item.name);
     });
   }
@@ -681,17 +680,15 @@ export class PoolFormComponent extends CdForm implements OnInit {
     }
     const name = value[nameAttribute];
     this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription,
-        itemNames: [name],
-        submitActionObservable: () => {
-          const deletion = deleteFn(name);
-          deletion.subscribe(() => reloadFn());
-          return this.taskWrapper.wrapTaskAroundCall({
-            task: new FinishedTask(taskName, { name: name }),
-            call: deletion
-          });
-        }
+      itemDescription,
+      itemNames: [name],
+      submitActionObservable: () => {
+        const deletion = deleteFn(name);
+        deletion.subscribe(() => reloadFn());
+        return this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask(taskName, { name: name }),
+          call: deletion
+        });
       }
     });
   }
index 3b1de559f302851b234def2b1e4712486a86d1a5..76a28e69c5e2585e3710b0e97e84a7e95a9fe773 100644 (file)
@@ -5,7 +5,6 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -19,6 +18,7 @@ import { PoolService } from '../../../shared/api/pool.service';
 import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
 import { ExecutingTask } from '../../../shared/models/executing-task';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { SummaryService } from '../../../shared/services/summary.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { SharedModule } from '../../../shared/shared.module';
@@ -151,7 +151,7 @@ describe('PoolListComponent', () => {
 
     const callDeletion = () => {
       component.deletePoolModal();
-      const deletion: CriticalConfirmationModalComponent = component.modalRef.content;
+      const deletion: CriticalConfirmationModalComponent = component.modalRef.componentInstance;
       deletion.submitActionObservable();
     };
 
@@ -171,9 +171,9 @@ describe('PoolListComponent', () => {
     };
 
     beforeEach(() => {
-      spyOn(TestBed.inject(BsModalService), 'show').and.callFake((deletionClass, config) => {
+      spyOn(TestBed.inject(ModalService), 'show').and.callFake((deletionClass, initialState) => {
         return {
-          content: Object.assign(new deletionClass(), config.initialState)
+          componentInstance: Object.assign(new deletionClass(), initialState)
         };
       });
       spyOn(poolService, 'delete').and.stub();
index b0d63284b0ac317c0c44a917a2973c6f6d071c0c..590a2b5c60f8da090ec6447024c2302f2979d406 100644 (file)
@@ -1,8 +1,8 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { ConfigurationService } from '../../../shared/api/configuration.service';
 import { PoolService } from '../../../shared/api/pool.service';
@@ -21,6 +21,7 @@ import { FinishedTask } from '../../../shared/models/finished-task';
 import { Permissions } from '../../../shared/models/permissions';
 import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { TaskListService } from '../../../shared/services/task-list.service';
 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
 import { URLBuilderService } from '../../../shared/services/url-builder.service';
@@ -51,7 +52,7 @@ export class PoolListComponent extends ListWithDetails implements OnInit {
   pools: Pool[];
   columns: CdTableColumn[];
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   executingTasks: ExecutingTask[] = [];
   permissions: Permissions;
   tableActions: CdTableAction[];
@@ -64,7 +65,7 @@ export class PoolListComponent extends ListWithDetails implements OnInit {
     private taskWrapper: TaskWrapperService,
     private authStorageService: AuthStorageService,
     private taskListService: TaskListService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private pgCategoryService: PgCategoryService,
     private dimlessPipe: DimlessPipe,
@@ -221,15 +222,13 @@ export class PoolListComponent extends ListWithDetails implements OnInit {
   deletePoolModal() {
     const name = this.selection.first().pool_name;
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'Pool',
-        itemNames: [name],
-        submitActionObservable: () =>
-          this.taskWrapper.wrapTaskAroundCall({
-            task: new FinishedTask(`${BASE_URL}/${URLVerbs.DELETE}`, { pool_name: name }),
-            call: this.poolService.delete(name)
-          })
-      }
+      itemDescription: 'Pool',
+      itemNames: [name],
+      submitActionObservable: () =>
+        this.taskWrapper.wrapTaskAroundCall({
+          task: new FinishedTask(`${BASE_URL}/${URLVerbs.DELETE}`, { pool_name: name }),
+          call: this.poolService.delete(name)
+        })
     });
   }
 
index 4cc380c3d16ba06eb6a73c9b4be243f0b8d6df06..51bb131eb843e7f48f50b85e8f677a6f8b2f238e 100644 (file)
@@ -4,7 +4,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
-import { ModalModule } from 'ngx-bootstrap/modal';
 import { of } from 'rxjs';
 
 import {
@@ -29,7 +28,6 @@ describe('RgwBucketListComponent', () => {
     imports: [
       BrowserAnimationsModule,
       RouterTestingModule,
-      ModalModule.forRoot(),
       SharedModule,
       NgbNavModule,
       HttpClientTestingModule
index cf7820b8edd65be3b05fa5ecb3234cbe3ea991cd..83c1c8cb9ae931198632dd130381d7bb202ba063 100644 (file)
@@ -9,7 +9,6 @@ import {
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
 
 import { RgwBucketService } from '../../../shared/api/rgw-bucket.service';
@@ -26,6 +25,7 @@ import { Permission } from '../../../shared/models/permissions';
 import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe';
 import { DimlessPipe } from '../../../shared/pipes/dimless.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { URLBuilderService } from '../../../shared/services/url-builder.service';
 
 const BASE_URL = 'rgw/bucket';
@@ -57,7 +57,7 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit {
     private dimlessBinaryPipe: DimlessBinaryPipe,
     private dimlessPipe: DimlessPipe,
     private rgwBucketService: RgwBucketService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     public actionLabels: ActionLabelsI18n,
@@ -182,36 +182,34 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit {
   }
 
   deleteAction() {
-    this.bsModalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: this.selection.hasSingleSelection
-          ? this.i18n('bucket')
-          : this.i18n('buckets'),
-        itemNames: this.selection.selected.map((bucket: any) => bucket['bid']),
-        submitActionObservable: () => {
-          return new Observable((observer: Subscriber<any>) => {
-            // Delete all selected data table rows.
-            observableForkJoin(
-              this.selection.selected.map((bucket: any) => {
-                return this.rgwBucketService.delete(bucket.bid);
-              })
-            ).subscribe({
-              error: (error) => {
-                // Forward the error to the observer.
-                observer.error(error);
-                // Reload the data table content because some deletions might
-                // have been executed successfully in the meanwhile.
-                this.table.refreshBtn();
-              },
-              complete: () => {
-                // Notify the observer that we are done.
-                observer.complete();
-                // Reload the data table content.
-                this.table.refreshBtn();
-              }
-            });
+    this.modalService.show(CriticalConfirmationModalComponent, {
+      itemDescription: this.selection.hasSingleSelection
+        ? this.i18n('bucket')
+        : this.i18n('buckets'),
+      itemNames: this.selection.selected.map((bucket: any) => bucket['bid']),
+      submitActionObservable: () => {
+        return new Observable((observer: Subscriber<any>) => {
+          // Delete all selected data table rows.
+          observableForkJoin(
+            this.selection.selected.map((bucket: any) => {
+              return this.rgwBucketService.delete(bucket.bid);
+            })
+          ).subscribe({
+            error: (error) => {
+              // Forward the error to the observer.
+              observer.error(error);
+              // Reload the data table content because some deletions might
+              // have been executed successfully in the meanwhile.
+              this.table.refreshBtn();
+            },
+            complete: () => {
+              // Notify the observer that we are done.
+              observer.complete();
+              // Reload the data table content.
+              this.table.refreshBtn();
+            }
           });
-        }
+        });
       }
     });
   }
index de9165c309a2997e19baa97d364b5b3e3753f838..e07155637f115fa880fccbf68965dedc4ade3476 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n="form title|Example: Create Pool@@formTitle"
                 class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
 
@@ -64,7 +64,7 @@
         <cd-submit-button (submitAction)="onSubmit()"
                           i18n="form action button|Example: Create Pool@@formActionButton"
                           [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="activeModal.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index c2b53d2620b1385df4f7e0b377c6476994fb0a61..9c457bec9c40c3f6f5055336d5a0403b0a546508 100644 (file)
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
@@ -15,7 +15,7 @@ describe('RgwUserCapabilityModalComponent', () => {
   configureTestBed({
     declarations: [RgwUserCapabilityModalComponent],
     imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index 50001eda91f228b304357643debc80bcb454ee04..cb4ca3855454d0c93f637421dfd2f0adc807b138 100644 (file)
@@ -1,9 +1,9 @@
 import { Component, EventEmitter, Output } from '@angular/core';
 import { Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
 import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
@@ -32,7 +32,7 @@ export class RgwUserCapabilityModalComponent {
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
   ) {
@@ -89,6 +89,6 @@ export class RgwUserCapabilityModalComponent {
   onSubmit() {
     const capability: RgwUserCapability = this.formGroup.value;
     this.submitAction.emit(capability);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
index 11a647690c3f75e2abf861673b0cfd308b4bf295..9dcf79a3c034b6a0c5ae1ceac39e1e9da2b19d3b 100644 (file)
@@ -3,7 +3,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 
 import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
-import { BsModalService } from 'ngx-bootstrap/modal';
 
 import { configureTestBed, i18nProviders, TabHelper } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
@@ -17,7 +16,7 @@ describe('RgwUserDetailsComponent', () => {
   configureTestBed({
     declarations: [RgwUserDetailsComponent],
     imports: [BrowserAnimationsModule, HttpClientTestingModule, SharedModule, NgbNavModule],
-    providers: [BsModalService, i18nProviders]
+    providers: [i18nProviders]
   });
 
   beforeEach(() => {
index bfd5683d7097bea784dd226ab758825251939722..f2cd8faa18b9a375787f89fba7450e32f6fd2f05 100644 (file)
@@ -2,12 +2,12 @@ import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@an
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 
 import { RgwUserService } from '../../../shared/api/rgw-user.service';
 import { Icons } from '../../../shared/enum/icons.enum';
 import { CdTableColumn } from '../../../shared/models/cd-table-column';
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
+import { ModalService } from '../../../shared/services/modal.service';
 import { RgwUserS3Key } from '../models/rgw-user-s3-key';
 import { RgwUserSwiftKey } from '../models/rgw-user-swift-key';
 import { RgwUserS3KeyModalComponent } from '../rgw-user-s3-key-modal/rgw-user-s3-key-modal.component';
@@ -40,7 +40,7 @@ export class RgwUserDetailsComponent implements OnChanges, OnInit {
 
   constructor(
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n
   ) {}
 
@@ -109,16 +109,16 @@ export class RgwUserDetailsComponent implements OnChanges, OnInit {
 
   showKeyModal() {
     const key = this.keysSelection.first();
-    const modalRef = this.bsModalService.show(
+    const modalRef = this.modalService.show(
       key.type === 'S3' ? RgwUserS3KeyModalComponent : RgwUserSwiftKeyModalComponent
     );
     switch (key.type) {
       case 'S3':
-        modalRef.content.setViewing();
-        modalRef.content.setValues(key.ref.user, key.ref.access_key, key.ref.secret_key);
+        modalRef.componentInstance.setViewing();
+        modalRef.componentInstance.setValues(key.ref.user, key.ref.access_key, key.ref.secret_key);
         break;
       case 'Swift':
-        modalRef.content.setValues(key.ref.user, key.ref.secret_key);
+        modalRef.componentInstance.setValues(key.ref.user, key.ref.secret_key);
         break;
     }
   }
index e297c330be08c2e298be33506ff5a2143d05dc6d..c41e7384d28b656e5803891b735b73099b02a7bb 100644 (file)
@@ -5,7 +5,6 @@ import { Router } from '@angular/router';
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of as observableOf } from 'rxjs';
 
@@ -35,7 +34,7 @@ describe('RgwUserFormComponent', () => {
       ToastrModule.forRoot(),
       NgbTooltipModule
     ],
-    providers: [BsModalService, i18nProviders]
+    providers: [i18nProviders]
   });
 
   beforeEach(() => {
index 44d1e1eddc94ba68c3445e3234f29bf8f5bdc6b6..00a799f180f8d452e28488fddf191a25ee26814d 100644 (file)
@@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router';
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { concat as observableConcat, forkJoin as observableForkJoin, Observable } from 'rxjs';
 
 import { RgwUserService } from '../../../shared/api/rgw-user.service';
@@ -16,6 +15,7 @@ import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { CdValidators, isEmptyInputValue } from '../../../shared/forms/cd-validators';
 import { FormatterService } from '../../../shared/services/formatter.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { RgwUserCapabilities } from '../models/rgw-user-capabilities';
 import { RgwUserCapability } from '../models/rgw-user-capability';
@@ -53,7 +53,7 @@ export class RgwUserFormComponent extends CdForm implements OnInit {
     private route: ActivatedRoute,
     private router: Router,
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
@@ -468,19 +468,19 @@ export class RgwUserFormComponent extends CdForm implements OnInit {
    */
   showSubuserModal(index?: number) {
     const uid = this.userForm.getValue('uid');
-    const modalRef = this.bsModalService.show(RgwUserSubuserModalComponent);
+    const modalRef = this.modalService.show(RgwUserSubuserModalComponent);
     if (_.isNumber(index)) {
       // Edit
       const subuser = this.subusers[index];
-      modalRef.content.setEditing();
-      modalRef.content.setValues(uid, subuser.id, subuser.permissions);
+      modalRef.componentInstance.setEditing();
+      modalRef.componentInstance.setValues(uid, subuser.id, subuser.permissions);
     } else {
       // Add
-      modalRef.content.setEditing(false);
-      modalRef.content.setValues(uid);
-      modalRef.content.setSubusers(this.subusers);
+      modalRef.componentInstance.setEditing(false);
+      modalRef.componentInstance.setValues(uid);
+      modalRef.componentInstance.setSubusers(this.subusers);
     }
-    modalRef.content.submitAction.subscribe((subuser: RgwUserSubuser) => {
+    modalRef.componentInstance.submitAction.subscribe((subuser: RgwUserSubuser) => {
       this.setSubuser(subuser, index);
     });
   }
@@ -490,18 +490,18 @@ export class RgwUserFormComponent extends CdForm implements OnInit {
    * @param {number | undefined} index The S3 key to show.
    */
   showS3KeyModal(index?: number) {
-    const modalRef = this.bsModalService.show(RgwUserS3KeyModalComponent);
+    const modalRef = this.modalService.show(RgwUserS3KeyModalComponent);
     if (_.isNumber(index)) {
       // View
       const key = this.s3Keys[index];
-      modalRef.content.setViewing();
-      modalRef.content.setValues(key.user, key.access_key, key.secret_key);
+      modalRef.componentInstance.setViewing();
+      modalRef.componentInstance.setValues(key.user, key.access_key, key.secret_key);
     } else {
       // Add
       const candidates = this._getS3KeyUserCandidates();
-      modalRef.content.setViewing(false);
-      modalRef.content.setUserCandidates(candidates);
-      modalRef.content.submitAction.subscribe((key: RgwUserS3Key) => {
+      modalRef.componentInstance.setViewing(false);
+      modalRef.componentInstance.setUserCandidates(candidates);
+      modalRef.componentInstance.submitAction.subscribe((key: RgwUserS3Key) => {
         this.setS3Key(key);
       });
     }
@@ -512,9 +512,9 @@ export class RgwUserFormComponent extends CdForm implements OnInit {
    * @param {number} index The Swift key to show.
    */
   showSwiftKeyModal(index: number) {
-    const modalRef = this.bsModalService.show(RgwUserSwiftKeyModalComponent);
+    const modalRef = this.modalService.show(RgwUserSwiftKeyModalComponent);
     const key = this.swiftKeys[index];
-    modalRef.content.setValues(key.user, key.secret_key);
+    modalRef.componentInstance.setValues(key.user, key.secret_key);
   }
 
   /**
@@ -522,18 +522,18 @@ export class RgwUserFormComponent extends CdForm implements OnInit {
    * @param {number | undefined} index The S3 key to show.
    */
   showCapabilityModal(index?: number) {
-    const modalRef = this.bsModalService.show(RgwUserCapabilityModalComponent);
+    const modalRef = this.modalService.show(RgwUserCapabilityModalComponent);
     if (_.isNumber(index)) {
       // Edit
       const cap = this.capabilities[index];
-      modalRef.content.setEditing();
-      modalRef.content.setValues(cap.type, cap.perm);
+      modalRef.componentInstance.setEditing();
+      modalRef.componentInstance.setValues(cap.type, cap.perm);
     } else {
       // Add
-      modalRef.content.setEditing(false);
-      modalRef.content.setCapabilities(this.capabilities);
+      modalRef.componentInstance.setEditing(false);
+      modalRef.componentInstance.setCapabilities(this.capabilities);
     }
-    modalRef.content.submitAction.subscribe((cap: RgwUserCapability) => {
+    modalRef.componentInstance.submitAction.subscribe((cap: RgwUserCapability) => {
       this.setCapability(cap, index);
     });
   }
index 12f7a1df2a06ff74b72bedee63a950e64b1e87ed..a893a0db1feaa113a37a7a8be4281be577145fec 100644 (file)
@@ -4,8 +4,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { ModalModule } from 'ngx-bootstrap/modal';
-
 import {
   configureTestBed,
   i18nProviders,
@@ -21,13 +19,7 @@ describe('RgwUserListComponent', () => {
 
   configureTestBed({
     declarations: [RgwUserListComponent],
-    imports: [
-      BrowserAnimationsModule,
-      RouterTestingModule,
-      HttpClientTestingModule,
-      ModalModule.forRoot(),
-      SharedModule
-    ],
+    imports: [BrowserAnimationsModule, RouterTestingModule, HttpClientTestingModule, SharedModule],
     schemas: [NO_ERRORS_SCHEMA],
     providers: i18nProviders
   });
index 7688c84484c0773ef66ddccc070998e3a57d79cf..4bad8007d7d0ac3ef9c2f51db9a80e4722ed3a5b 100644 (file)
@@ -1,7 +1,6 @@
 import { Component, NgZone, ViewChild } from '@angular/core';
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs';
 
 import { RgwUserService } from '../../../shared/api/rgw-user.service';
@@ -17,6 +16,7 @@ import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-d
 import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { Permission } from '../../../shared/models/permissions';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { URLBuilderService } from '../../../shared/services/url-builder.service';
 
 const BASE_URL = 'rgw/user';
@@ -41,7 +41,7 @@ export class RgwUserListComponent extends ListWithDetails {
   constructor(
     private authStorageService: AuthStorageService,
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     public actionLabels: ActionLabelsI18n,
@@ -139,34 +139,32 @@ export class RgwUserListComponent extends ListWithDetails {
   }
 
   deleteAction() {
-    this.bsModalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: this.selection.hasSingleSelection ? this.i18n('user') : this.i18n('users'),
-        itemNames: this.selection.selected.map((user: any) => user['uid']),
-        submitActionObservable: (): Observable<any> => {
-          return new Observable((observer: Subscriber<any>) => {
-            // Delete all selected data table rows.
-            observableForkJoin(
-              this.selection.selected.map((user: any) => {
-                return this.rgwUserService.delete(user.uid);
-              })
-            ).subscribe({
-              error: (error) => {
-                // Forward the error to the observer.
-                observer.error(error);
-                // Reload the data table content because some deletions might
-                // have been executed successfully in the meanwhile.
-                this.table.refreshBtn();
-              },
-              complete: () => {
-                // Notify the observer that we are done.
-                observer.complete();
-                // Reload the data table content.
-                this.table.refreshBtn();
-              }
-            });
+    this.modalService.show(CriticalConfirmationModalComponent, {
+      itemDescription: this.selection.hasSingleSelection ? this.i18n('user') : this.i18n('users'),
+      itemNames: this.selection.selected.map((user: any) => user['uid']),
+      submitActionObservable: (): Observable<any> => {
+        return new Observable((observer: Subscriber<any>) => {
+          // Delete all selected data table rows.
+          observableForkJoin(
+            this.selection.selected.map((user: any) => {
+              return this.rgwUserService.delete(user.uid);
+            })
+          ).subscribe({
+            error: (error) => {
+              // Forward the error to the observer.
+              observer.error(error);
+              // Reload the data table content because some deletions might
+              // have been executed successfully in the meanwhile.
+              this.table.refreshBtn();
+            },
+            complete: () => {
+              // Notify the observer that we are done.
+              observer.complete();
+              // Reload the data table content.
+              this.table.refreshBtn();
+            }
           });
-        }
+        });
       }
     });
   }
index b82f23070ff07b4d9a0668548ee7ff3b00288653..a6f73722dcebe7366808dcb24bc7f71ffd9d3790 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n="form title|Example: Create Pool@@formTitle"
                 class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
 
                           (submitAction)="onSubmit()"
                           i18n="form action button|Example: Create Pool@@formActionButton"
                           [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="activeModal.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index bf8dcdce7510927e94006cd4f00ce2e8cc6e1852..0f124dcb2ff8208fa586fe1f3782997225d8f2c7 100644 (file)
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
@@ -15,7 +15,7 @@ describe('RgwUserS3KeyModalComponent', () => {
   configureTestBed({
     declarations: [RgwUserS3KeyModalComponent],
     imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index a3cd2f1167e43ff775d09fd111e8fc9eb41bbeca..bc762794d68d9143e6a58859e5d2330dbfb0c5db 100644 (file)
@@ -1,9 +1,9 @@
 import { Component, EventEmitter, Output } from '@angular/core';
 import { Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
 import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
@@ -31,7 +31,7 @@ export class RgwUserS3KeyModalComponent {
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
   ) {
@@ -81,6 +81,6 @@ export class RgwUserS3KeyModalComponent {
   onSubmit() {
     const key: RgwUserS3Key = this.formGroup.value;
     this.submitAction.emit(key);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
index 578324221e0702111a95f81ae47bc185f70339ff..7ad3d10962d8f438e69d69a07b5f1b1c401b6025 100644 (file)
         <cd-submit-button (submitAction)="onSubmit()"
                           i18n="form action button|Example: Create Pool@@formActionButton"
                           [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="bsModalRef.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index a828c3d5df028708646f224a9974abc1383f1f8a..4c883468e7fb5d0a3a0b2227a0db7facd6577c09 100644 (file)
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { FormControl, ReactiveFormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { SharedModule } from '../../../shared/shared.module';
@@ -15,7 +15,7 @@ describe('RgwUserSubuserModalComponent', () => {
   configureTestBed({
     declarations: [RgwUserSubuserModalComponent],
     imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index 04623f8c26d3bb960657ed984d102bce4c3f8fe8..663c7f937794caa6884405d49dd69f977a2e21d5 100644 (file)
@@ -1,9 +1,9 @@
 import { Component, EventEmitter, Output } from '@angular/core';
 import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
 import { CdFormBuilder } from '../../../shared/forms/cd-form-builder';
@@ -32,7 +32,7 @@ export class RgwUserSubuserModalComponent {
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public bsModalRef: NgbActiveModal,
     private i18n: I18n,
     private actionLabels: ActionLabelsI18n
   ) {
@@ -127,6 +127,6 @@ export class RgwUserSubuserModalComponent {
     subuser.generate_secret = values.generate_secret;
     subuser.secret_key = values.secret_key;
     this.submitAction.emit(subuser);
-    this.bsModalRef.hide();
+    this.bsModalRef.close();
   }
 }
index 5e74d7e3547a774dae8ed4cfe6821922ed1cf8f0..320d9d7f6048cb2d4dfc75735d5c9a4a2cdca4b3 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n="form title|Example: Create Pool@@formTitle"
                 class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}
   </ng-container>
@@ -51,7 +51,7 @@
     </div>
 
     <div class="modal-footer">
-      <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+      <cd-back-button [back]="activeModal.close"></cd-back-button>
     </div>
   </ng-container>
 </cd-modal>
index 38d9bde31a3ef9b61267feefca5649b68f97e0c3..af2c873bcdb8a9a96910a41788aa581b20314d2b 100644 (file)
@@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { FormsModule } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
@@ -16,7 +16,7 @@ describe('RgwUserSwiftKeyModalComponent', () => {
   configureTestBed({
     declarations: [RgwUserSwiftKeyModalComponent],
     imports: [ToastrModule.forRoot(), FormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index ad10e070f7e6db6eda8b87c2158420b968389744..aa34f6b7c7f0b9e99639cdc66c0623edae00d763 100644 (file)
@@ -1,7 +1,7 @@
 import { Component } from '@angular/core';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { ActionLabelsI18n } from '../../../shared/constants/app.constants';
 
@@ -17,7 +17,7 @@ export class RgwUserSwiftKeyModalComponent {
   action: string;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
   ) {
index 6396f5d59eb29a06d90676adee55d40ac4c86c49..bef59ffb1dc4c9a0098688cd437d7a13ab00171b 100644 (file)
@@ -5,7 +5,6 @@ import { RouterModule, Routes } from '@angular/router';
 
 import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
-import { ModalModule } from 'ngx-bootstrap/modal';
 
 import { ActionLabels, URLVerbs } from '../../shared/constants/app.constants';
 import { AuthGuardService } from '../../shared/services/auth-guard.service';
@@ -33,7 +32,6 @@ import { RgwUserSwiftKeyModalComponent } from './rgw-user-swift-key-modal/rgw-us
     ReactiveFormsModule,
     PerformanceCounterModule,
     NgbNavModule,
-    ModalModule.forRoot(),
     RouterModule,
     NgBootstrapFormValidationModule,
     NgbTooltipModule
index daa96f34e8bfda92edd00912fa19859a81d770cf..e162d3721dc28913272ccacdcdb2dd9534eb07c7 100644 (file)
@@ -25,8 +25,8 @@ describe('LoginComponent', () => {
   });
 
   it('should ensure no modal dialogs are opened', () => {
-    component['bsModalService']['modalsCount'] = 2;
+    component['modalService']['modalsCount'] = 2;
     component.ngOnInit();
-    expect(component['bsModalService'].getModalsCount()).toBe(0);
+    expect(component['modalService'].hasOpenModals()).toBeFalsy();
   });
 });
index 9286e31d30f107ea11a64662cdd9111cbacbda0b..0703268a0237dde0e9ba0c84995a45f7e9c7d2ae 100644 (file)
@@ -1,11 +1,10 @@
 import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
 
-import { BsModalService } from 'ngx-bootstrap/modal';
-
 import { AuthService } from '../../../shared/api/auth.service';
 import { Credentials } from '../../../shared/models/credentials';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 
 @Component({
   selector: 'cd-login',
@@ -19,7 +18,7 @@ export class LoginComponent implements OnInit {
   constructor(
     private authService: AuthService,
     private authStorageService: AuthStorageService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private router: Router
   ) {}
 
@@ -30,10 +29,7 @@ export class LoginComponent implements OnInit {
       // Make sure all open modal dialogs are closed. This might be
       // necessary when the logged in user is redirected to the login
       // page after a 401.
-      const modalsCount = this.bsModalService.getModalsCount();
-      for (let i = 1; i <= modalsCount; i++) {
-        this.bsModalService.hide(i);
-      }
+      this.modalService.dismissAll();
 
       let token: string = null;
       if (window.location.hash.indexOf('access_token=') !== -1) {
index 24e38b2d6b96c9a4906c30b39f0f020f1455d9fb..e042a4f2f26fc3cc7c3bbc4df4c49661264e9885 100644 (file)
@@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router';
 
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin } from 'rxjs';
 
 import { RoleService } from '../../../shared/api/role.service';
@@ -32,8 +31,6 @@ export class RoleFormComponent extends CdForm implements OnInit {
   @ViewChild('cellPermissionCheckboxTpl', { static: true })
   cellPermissionCheckboxTpl: TemplateRef<any>;
 
-  modalRef: BsModalRef;
-
   roleForm: CdFormGroup;
   response: RoleFormModel;
 
index a945b79fae4d9751a9083ae333bfba71ed8c29c1..f1cd8753868ee4aa9c6958376fbbeea63df0f80b 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnInit } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin } from 'rxjs';
 
 import { RoleService } from '../../../shared/api/role.service';
@@ -19,6 +19,7 @@ import { CdTableSelection } from '../../../shared/models/cd-table-selection';
 import { Permission } from '../../../shared/models/permissions';
 import { EmptyPipe } from '../../../shared/pipes/empty.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { URLBuilderService } from '../../../shared/services/url-builder.service';
 
@@ -38,14 +39,14 @@ export class RoleListComponent extends ListWithDetails implements OnInit {
   scopes: Array<string>;
   selection = new CdTableSelection();
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   constructor(
     private roleService: RoleService,
     private scopeService: ScopeService,
     private emptyPipe: EmptyPipe,
     private authStorageService: AuthStorageService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
@@ -124,14 +125,14 @@ export class RoleListComponent extends ListWithDetails implements OnInit {
     this.roleService.delete(role).subscribe(
       () => {
         this.getRoles();
-        this.modalRef.hide();
+        this.modalRef.close();
         this.notificationService.show(
           NotificationType.success,
           this.i18n(`Deleted role '{{role_name}}'`, { role_name: role })
         );
       },
       () => {
-        this.modalRef.content.stopLoadingSpinner();
+        this.modalRef.componentInstance.stopLoadingSpinner();
       }
     );
   }
@@ -139,41 +140,37 @@ export class RoleListComponent extends ListWithDetails implements OnInit {
   deleteRoleModal() {
     const name = this.selection.first().name;
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'Role',
-        itemNames: [name],
-        submitAction: () => this.deleteRole(name)
-      }
+      itemDescription: 'Role',
+      itemNames: [name],
+      submitAction: () => this.deleteRole(name)
     });
   }
 
   cloneRole() {
     const name = this.selection.first().name;
     this.modalRef = this.modalService.show(FormModalComponent, {
-      initialState: {
-        fields: [
-          {
-            type: 'text',
-            name: 'newName',
-            value: `${name}_clone`,
-            label: this.i18n('New name'),
-            required: true
-          }
-        ],
-        titleText: this.i18n('Clone Role'),
-        submitButtonText: this.i18n('Clone Role'),
-        onSubmit: (values: object) => {
-          this.roleService.clone(name, values['newName']).subscribe(() => {
-            this.getRoles();
-            this.notificationService.show(
-              NotificationType.success,
-              this.i18n(`Cloned role '{{dst_name}}' from '{{src_name}}'`, {
-                src_name: name,
-                dst_name: values['newName']
-              })
-            );
-          });
+      fields: [
+        {
+          type: 'text',
+          name: 'newName',
+          value: `${name}_clone`,
+          label: this.i18n('New name'),
+          required: true
         }
+      ],
+      titleText: this.i18n('Clone Role'),
+      submitButtonText: this.i18n('Clone Role'),
+      onSubmit: (values: object) => {
+        this.roleService.clone(name, values['newName']).subscribe(() => {
+          this.getRoles();
+          this.notificationService.show(
+            NotificationType.success,
+            this.i18n(`Cloned role '{{dst_name}}' from '{{src_name}}'`, {
+              src_name: name,
+              dst_name: values['newName']
+            })
+          );
+        });
       }
     });
   }
index df3bc8b08d4eb755a232a7b0e1e34feef6e0f9b0..3d79fc97a84dcac6ffa857d5119c399ef805d13f 100644 (file)
@@ -7,7 +7,6 @@ import { RouterTestingModule } from '@angular/router/testing';
 
 import { ButtonsModule } from 'ngx-bootstrap/buttons';
 import { BsDatepickerModule } from 'ngx-bootstrap/datepicker';
-import { BsModalService } from 'ngx-bootstrap/modal';
 import { ToastrModule } from 'ngx-toastr';
 import { of } from 'rxjs';
 
@@ -19,6 +18,7 @@ import { ComponentsModule } from '../../../shared/components/components.module';
 import { LoadingPanelComponent } from '../../../shared/components/loading-panel/loading-panel.component';
 import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { SharedModule } from '../../../shared/shared.module';
 import { PasswordPolicyService } from './../../../shared/services/password-policy.service';
@@ -31,7 +31,7 @@ describe('UserFormComponent', () => {
   let fixture: ComponentFixture<UserFormComponent>;
   let httpTesting: HttpTestingController;
   let userService: UserService;
-  let modalService: BsModalService;
+  let modalService: ModalService;
   let router: Router;
   let formHelper: FormHelper;
 
@@ -70,7 +70,7 @@ describe('UserFormComponent', () => {
     form = component.userForm;
     httpTesting = TestBed.inject(HttpTestingController);
     userService = TestBed.inject(UserService);
-    modalService = TestBed.inject(BsModalService);
+    modalService = TestBed.inject(ModalService);
     router = TestBed.inject(Router);
     spyOn(router, 'navigate');
     fixture.detectChanges();
@@ -221,8 +221,8 @@ describe('UserFormComponent', () => {
     it('should alert if user is removing needed role permission', () => {
       spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username);
       let modalBodyTpl = null;
-      spyOn(modalService, 'show').and.callFake((_content, config) => {
-        modalBodyTpl = config.initialState.bodyTpl;
+      spyOn(modalService, 'show').and.callFake((_content, initialState) => {
+        modalBodyTpl = initialState.bodyTpl;
       });
       formHelper.setValue('roles', ['read-only']);
       component.submit();
index 9bd83ac16758d27bbd5fdc474157902662133679..1489b433b53c270ff90507a15d8cfb6f5049a151 100644 (file)
@@ -2,9 +2,9 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 import { Validators } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 import { forkJoin as observableForkJoin } from 'rxjs';
 
 import { AuthService } from '../../../shared/api/auth.service';
@@ -22,6 +22,7 @@ import { CdFormGroup } from '../../../shared/forms/cd-form-group';
 import { CdValidators } from '../../../shared/forms/cd-validators';
 import { CdPwdExpirationSettings } from '../../../shared/models/cd-pwd-expiration-settings';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { PasswordPolicyService } from '../../../shared/services/password-policy.service';
 import { UserFormMode } from './user-form-mode.enum';
@@ -37,7 +38,7 @@ export class UserFormComponent extends CdForm implements OnInit {
   @ViewChild('removeSelfUserReadUpdatePermissionTpl', { static: true })
   removeSelfUserReadUpdatePermissionTpl: TemplateRef<any>;
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   userForm: CdFormGroup;
   response: UserFormModel;
@@ -64,7 +65,7 @@ export class UserFormComponent extends CdForm implements OnInit {
     private authStorageService: AuthStorageService,
     private route: ActivatedRoute,
     public router: Router,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private roleService: RoleService,
     private userService: UserService,
     private notificationService: NotificationService,
@@ -226,7 +227,7 @@ export class UserFormComponent extends CdForm implements OnInit {
         buttonText: this.i18n('Continue'),
         bodyTpl: this.removeSelfUserReadUpdatePermissionTpl,
         onSubmit: () => {
-          this.modalRef.hide();
+          this.modalRef.close();
           this.doEditAction();
         },
         onCancel: () => {
@@ -234,7 +235,7 @@ export class UserFormComponent extends CdForm implements OnInit {
           this.userForm.get('roles').reset(this.userForm.get('roles').value);
         }
       };
-      this.modalRef = this.modalService.show(ConfirmationModalComponent, { initialState });
+      this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState);
     } else {
       this.doEditAction();
     }
index 9f2a6207f0702286cc10da878133c17d46341053..53e031a5d5965ea528424b83138435fe9ab73b3a 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
 
 import { UserService } from '../../../shared/api/user.service';
 import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component';
@@ -16,6 +16,7 @@ import { Permission } from '../../../shared/models/permissions';
 import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe';
 import { EmptyPipe } from '../../../shared/pipes/empty.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { NotificationService } from '../../../shared/services/notification.service';
 import { URLBuilderService } from '../../../shared/services/url-builder.service';
 
@@ -39,12 +40,12 @@ export class UserListComponent implements OnInit {
   users: Array<any>;
   selection = new CdTableSelection();
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   constructor(
     private userService: UserService,
     private emptyPipe: EmptyPipe,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private authStorageService: AuthStorageService,
     private i18n: I18n,
@@ -134,14 +135,14 @@ export class UserListComponent implements OnInit {
     this.userService.delete(username).subscribe(
       () => {
         this.getUsers();
-        this.modalRef.hide();
+        this.modalRef.close();
         this.notificationService.show(
           NotificationType.success,
           this.i18n(`Deleted user '{{username}}'`, { username: username })
         );
       },
       () => {
-        this.modalRef.content.stopLoadingSpinner();
+        this.modalRef.componentInstance.stopLoadingSpinner();
       }
     );
   }
@@ -157,12 +158,11 @@ export class UserListComponent implements OnInit {
       );
       return;
     }
+
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'User',
-        itemNames: [username],
-        submitAction: () => this.deleteUser(username)
-      }
+      itemDescription: 'User',
+      itemNames: [username],
+      submitAction: () => this.deleteUser(username)
     });
   }
 }
index 8727b8dcc3ad25b6e1d1a4799cf88591d4ce743a..2ac7476e3906633b919fc106261d40e899b77cff 100644 (file)
@@ -3,7 +3,7 @@
     <button type="button"
             class="close float-right"
             aria-label="Close"
-            (click)="modalRef.hide()">
+            (click)="activeModal.close()">
       <span aria-hidden="true">&times;</span>
     </button>
   </div>
index 996accd2230b1acde5866c75e2d4c0e3915b88e4..a636f7fbe10628e8bffd2df63496524e08c8638b 100644 (file)
@@ -1,7 +1,7 @@
 import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { BehaviorSubject } from 'rxjs';
 
 import { configureTestBed } from '../../../../testing/unit-test-helper';
@@ -30,7 +30,7 @@ describe('AboutComponent', () => {
   configureTestBed({
     imports: [SharedModule, HttpClientTestingModule],
     declarations: [AboutComponent],
-    providers: [BsModalRef, { provide: SummaryService, useClass: SummaryServiceMock }]
+    providers: [NgbActiveModal, { provide: SummaryService, useClass: SummaryServiceMock }]
   });
 
   beforeEach(() => {
index 6b77c8f94ee3f4a4054372cdcfba13ca3ae3fd05..6f885a9e6e8169f5d7ba77a88f69409938a9dd05 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnDestroy, OnInit } from '@angular/core';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { detect } from 'detect-browser';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 import { Subscription } from 'rxjs';
 
 import { environment } from '../../../../environments/environment';
@@ -28,7 +28,7 @@ export class AboutComponent implements OnInit, OnDestroy {
   copyright: string;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private summaryService: SummaryService,
     private userService: UserService,
     private authStorageService: AuthStorageService
index e6821ddf960ff137a01487745975e21023ecb7ac..8ec1046662939299609152129d276bf0ea220d6d 100644 (file)
@@ -1,10 +1,11 @@
 import { Component, OnInit, ViewChild } from '@angular/core';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
+import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 
 import { Icons } from '../../../shared/enum/icons.enum';
 import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe';
 import { AuthStorageService } from '../../../shared/services/auth-storage.service';
+import { ModalService } from '../../../shared/services/modal.service';
 import { SummaryService } from '../../../shared/services/summary.service';
 import { AboutComponent } from '../about/about.component';
 
@@ -17,13 +18,13 @@ export class DashboardHelpComponent implements OnInit {
   @ViewChild('docsForm', { static: true })
   docsFormElement: any;
   docsUrl: string;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   icons = Icons;
 
   constructor(
     private summaryService: SummaryService,
     private cephReleaseNamePipe: CephReleaseNamePipe,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private authStorageService: AuthStorageService
   ) {}
 
@@ -35,8 +36,7 @@ export class DashboardHelpComponent implements OnInit {
   }
 
   openAboutModal() {
-    this.modalRef = this.modalService.show(AboutComponent);
-    this.modalRef.setClass('modal-lg');
+    this.modalRef = this.modalService.show(AboutComponent, null, { size: 'lg' });
   }
 
   goToApiDocs() {
index 55a2779a0402684c5d47b4a8a5ec498d38dc1021..5b615dbcb5c21c27adafe51d30b0faf8a262cea4 100644 (file)
@@ -13,7 +13,6 @@ import {
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
 import { ClickOutsideModule } from 'ng-click-outside';
 import { ChartsModule } from 'ng2-charts';
-import { ModalModule } from 'ngx-bootstrap/modal';
 import { SimplebarAngularModule } from 'simplebar-angular';
 
 import { DirectivesModule } from '../directives/directives.module';
@@ -54,7 +53,6 @@ import { ViewCacheComponent } from './view-cache/view-cache.component';
     ChartsModule,
     ReactiveFormsModule,
     PipesModule,
-    ModalModule.forRoot(),
     DirectivesModule,
     NgbDropdownModule,
     NgBootstrapFormValidationModule,
index d64a56d146058cb5f9891f41e844abcb7bb7d8cf..c66910a5ea2fc513779640b8a4774501ddb0f8cd 100644 (file)
@@ -4,14 +4,14 @@ import { ReactiveFormsModule } from '@angular/forms';
 import { By } from '@angular/platform-browser';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal';
+import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 
 import {
   configureTestBed,
   FixtureHelper,
-  i18nProviders,
-  modalServiceShow
+  i18nProviders
 } from '../../../../testing/unit-test-helper';
+import { ModalService } from '../../services/modal.service';
 import { BackButtonComponent } from '../back-button/back-button.component';
 import { ModalComponent } from '../modal/modal.component';
 import { SubmitButtonComponent } from '../submit-button/submit-button.component';
@@ -30,15 +30,16 @@ export class MockModule {}
 class MockComponent {
   @ViewChild('fillTpl', { static: true })
   fillTpl: TemplateRef<any>;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   returnValue: any;
 
   // Normally private, but public is needed by tests
-  constructor(public modalService: BsModalService) {}
+  constructor(public modalService: ModalService) {}
 
   private openModal(extendBaseState = {}) {
-    this.modalRef = this.modalService.show(ConfirmationModalComponent, {
-      initialState: Object.assign(
+    this.modalRef = this.modalService.show(
+      ConfirmationModalComponent,
+      Object.assign(
         {
           titleText: 'Title is a must have',
           buttonText: 'Action label',
@@ -46,12 +47,11 @@ class MockComponent {
           description: 'String based description.',
           onSubmit: () => {
             this.returnValue = 'The submit action has to hide manually.';
-            this.modalRef.hide();
           }
         },
         extendBaseState
       )
-    });
+    );
   }
 
   basicModal() {
@@ -70,17 +70,8 @@ describe('ConfirmationModalComponent', () => {
   let fixture: ComponentFixture<ConfirmationModalComponent>;
   let mockComponent: MockComponent;
   let mockFixture: ComponentFixture<MockComponent>;
-  let modalService: BsModalService;
   let fh: FixtureHelper;
 
-  /**
-   * The hide method of `BsModalService` doesn't emit events during tests that's why it's mocked.
-   *
-   * The only events of hide are `null`, `'backdrop-click'` and `'esc'` as described here:
-   * https://ngx-universal.herokuapp.com/#/modals#service-events
-   */
-  const hide = (x: string) => modalService.onHide.emit(null || x);
-
   const expectReturnValue = (v: string) => expect(mockComponent.returnValue).toBe(v);
 
   configureTestBed({
@@ -92,8 +83,8 @@ describe('ConfirmationModalComponent', () => {
       SubmitButtonComponent
     ],
     schemas: [NO_ERRORS_SCHEMA],
-    imports: [ModalModule.forRoot(), ReactiveFormsModule, MockModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders, SubmitButtonComponent]
+    imports: [ReactiveFormsModule, MockModule, RouterTestingModule, NgbModalModule],
+    providers: [NgbActiveModal, i18nProviders, SubmitButtonComponent]
   });
 
   beforeEach(() => {
@@ -101,14 +92,14 @@ describe('ConfirmationModalComponent', () => {
     mockFixture = TestBed.createComponent(MockComponent);
     mockComponent = mockFixture.componentInstance;
     mockFixture.detectChanges();
-    modalService = TestBed.inject(BsModalService);
-    spyOn(modalService, 'show').and.callFake((_modalComp, config) => {
-      const data = modalServiceShow(ConfirmationModalComponent, config);
-      fixture = data.fixture;
-      component = data.component;
-      spyOn(component.modalRef, 'hide').and.callFake(hide);
+
+    spyOn(TestBed.inject(ModalService), 'show').and.callFake((_modalComp, config) => {
+      fixture = TestBed.createComponent(ConfirmationModalComponent);
+      component = fixture.componentInstance;
+      component = Object.assign(component, config);
+      component.activeModal = { close: () => true } as any;
+      spyOn(component.activeModal, 'close').and.callThrough();
       fh.updateFixture(fixture);
-      return data.ref;
     });
   });
 
@@ -165,7 +156,7 @@ describe('ConfirmationModalComponent', () => {
   describe('basics', () => {
     beforeEach(() => {
       mockComponent.basicModal();
-      spyOn(mockComponent.modalRef, 'hide').and.callFake(hide);
+      spyOn(component, 'onSubmit').and.callThrough();
     });
 
     it('should show the correct title', () => {
@@ -183,15 +174,15 @@ describe('ConfirmationModalComponent', () => {
         'focusButton'
       );
       fh.clickElement('.tc_submitButton');
-      expect(mockComponent.modalRef.hide).toHaveBeenCalledTimes(1);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(0);
+      expect(component.onSubmit).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(0);
       expectReturnValue('The submit action has to hide manually.');
     });
 
     it('should use the default cancel action', () => {
       fh.clickElement('.tc_backButton');
-      expect(mockComponent.modalRef.hide).toHaveBeenCalledTimes(0);
-      expect(component.modalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.onSubmit).toHaveBeenCalledTimes(0);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
       expectReturnValue(undefined);
     });
 
@@ -201,38 +192,4 @@ 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 87383eedff3d7ce5a85b518d08cee6f834111d03..bdd233cefc1ce905ed234e1827966939166ef8d0 100644 (file)
@@ -1,8 +1,7 @@
 import { Component, OnDestroy, OnInit, TemplateRef } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 
-import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal';
-import { Subscription } from 'rxjs';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 @Component({
   selector: 'cd-confirmation-modal',
@@ -27,16 +26,10 @@ 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, private modalService: BsModalService) {
+  constructor(public activeModal: NgbActiveModal) {
     this.confirmationForm = new FormGroup({});
-    this.onHide = this.modalService.onHide.subscribe((e: any) => {
-      if (this.onCancel && (e || this.canceled)) {
-        this.onCancel();
-      }
-    });
   }
 
   ngOnInit() {
@@ -54,12 +47,14 @@ export class ConfirmationModalComponent implements OnInit, OnDestroy {
   }
 
   ngOnDestroy() {
-    this.onHide.unsubscribe();
+    if (this.onCancel && this.canceled) {
+      this.onCancel();
+    }
   }
 
   cancel() {
     this.canceled = true;
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 
   stopLoadingSpinner() {
index ed834b0897f71556ee2f4d09e7e24c7f8a03eec3..4d70814547674121bd9420fdca5e89f8ffc93633 100644 (file)
@@ -1,5 +1,5 @@
 <cd-modal #modal
-          [modalRef]="modalRef">
+          [modalRef]="activeModal">
   <ng-container class="modal-title">
     <ng-container *ngTemplateOutlet="deletionHeading"></ng-container>
   </ng-container>
@@ -47,7 +47,7 @@
                           (submitAction)="callSubmitAction()">
           <ng-container *ngTemplateOutlet="deletionHeading"></ng-container>
         </cd-submit-button>
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Cancel"
                         i18n-name>
         </cd-back-button>
index f0a7cb7c4c375979245863ac7aa3aae941d9bcb5..3223256e9b9b70534eb28a6e34814cbaca20971d 100644 (file)
@@ -1,13 +1,13 @@
 import { Component, NgModule, NO_ERRORS_SCHEMA, TemplateRef, ViewChild } from '@angular/core';
 import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
 import { NgForm, ReactiveFormsModule } from '@angular/forms';
-import { By } from '@angular/platform-browser';
 
-import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal';
+import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { Observable, Subscriber, timer as observableTimer } from 'rxjs';
 
 import { configureTestBed, modalServiceShow } from '../../../../testing/unit-test-helper';
 import { DirectivesModule } from '../../directives/directives.module';
+import { ModalService } from '../../services/modal.service';
 import { AlertPanelComponent } from '../alert-panel/alert-panel.component';
 import { LoadingPanelComponent } from '../loading-panel/loading-panel.component';
 import { CriticalConfirmationModalComponent } from './critical-confirmation-modal.component';
@@ -40,27 +40,23 @@ class MockComponent {
   modalDescription: TemplateRef<any>;
   someData = [1, 2, 3, 4, 5];
   finished: number[];
-  ctrlRef: BsModalRef;
-  modalRef: BsModalRef;
+  ctrlRef: NgbModalRef;
+  modalRef: NgbModalRef;
 
   // Normally private - public was needed for the tests
-  constructor(public modalService: BsModalService) {}
+  constructor(public modalService: ModalService) {}
 
   openCtrlDriven() {
     this.ctrlRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        submitAction: this.fakeDeleteController.bind(this),
-        bodyTemplate: this.ctrlDescription
-      }
+      submitAction: this.fakeDeleteController.bind(this),
+      bodyTemplate: this.ctrlDescription
     });
   }
 
   openModalDriven() {
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        submitActionObservable: this.fakeDelete(),
-        bodyTemplate: this.modalDescription
-      }
+      submitActionObservable: this.fakeDelete(),
+      bodyTemplate: this.modalDescription
     });
   }
 
@@ -82,7 +78,7 @@ class MockComponent {
   fakeDeleteController() {
     observableTimer(100).subscribe(() => {
       this.finish();
-      this.ctrlRef.hide();
+      this.ctrlRef.close();
     });
   }
 }
@@ -91,28 +87,29 @@ describe('CriticalConfirmationModalComponent', () => {
   let mockComponent: MockComponent;
   let component: CriticalConfirmationModalComponent;
   let mockFixture: ComponentFixture<MockComponent>;
-  let fixture: ComponentFixture<CriticalConfirmationModalComponent>;
-
-  configureTestBed({
-    declarations: [
-      MockComponent,
-      CriticalConfirmationModalComponent,
-      LoadingPanelComponent,
-      AlertPanelComponent
-    ],
-    schemas: [NO_ERRORS_SCHEMA],
-    imports: [ModalModule.forRoot(), ReactiveFormsModule, MockModule, DirectivesModule],
-    providers: [BsModalRef]
-  });
+
+  configureTestBed(
+    {
+      declarations: [
+        MockComponent,
+        CriticalConfirmationModalComponent,
+        LoadingPanelComponent,
+        AlertPanelComponent
+      ],
+      schemas: [NO_ERRORS_SCHEMA],
+      imports: [ReactiveFormsModule, MockModule, DirectivesModule, NgbModalModule],
+      providers: [NgbActiveModal]
+    },
+    [CriticalConfirmationModalComponent]
+  );
 
   beforeEach(() => {
     mockFixture = TestBed.createComponent(MockComponent);
     mockComponent = mockFixture.componentInstance;
     spyOn(mockComponent.modalService, 'show').and.callFake((_modalComp, config) => {
       const data = modalServiceShow(CriticalConfirmationModalComponent, config);
-      fixture = data.fixture;
-      component = data.component;
-      return data.ref;
+      component = data.componentInstance;
+      return data;
     });
     mockComponent.openCtrlDriven();
     mockFixture.detectChanges();
@@ -122,18 +119,6 @@ describe('CriticalConfirmationModalComponent', () => {
     expect(component).toBeTruthy();
   });
 
-  it('should focus the checkbox form field', (done) => {
-    fixture.detectChanges();
-    fixture.whenStable().then(() => {
-      const focused = fixture.debugElement.query(By.css(':focus'));
-      expect(focused.attributes.id).toBe('confirmation');
-      expect(focused.attributes.type).toBe('checkbox');
-      const element = document.getElementById('confirmation');
-      expect(element === document.activeElement).toBeTruthy();
-      done();
-    });
-  });
-
   it('should throw an error if no action is defined', () => {
     component = Object.assign(component, {
       submitAction: null,
@@ -161,16 +146,16 @@ describe('CriticalConfirmationModalComponent', () => {
       ctrl.setValue(value);
       ctrl.markAsDirty();
       ctrl.updateValueAndValidity();
-      fixture.detectChanges();
+      mockFixture.detectChanges();
     };
 
     it('should test hideModal', () => {
-      expect(component.modalRef).toBeTruthy();
+      expect(component.activeModal).toBeTruthy();
       expect(component.hideModal).toBeTruthy();
-      spyOn(component.modalRef, 'hide').and.callThrough();
-      expect(component.modalRef.hide).not.toHaveBeenCalled();
+      spyOn(component.activeModal, 'close').and.callThrough();
+      expect(component.activeModal.close).not.toHaveBeenCalled();
       component.hideModal();
-      expect(component.modalRef.hide).toHaveBeenCalled();
+      expect(component.activeModal.close).toHaveBeenCalled();
     });
 
     describe('validate confirmation', () => {
@@ -204,7 +189,7 @@ describe('CriticalConfirmationModalComponent', () => {
       describe('Controller driven', () => {
         beforeEach(() => {
           spyOn(component, 'submitAction').and.callThrough();
-          spyOn(mockComponent.ctrlRef, 'hide').and.callThrough();
+          spyOn(mockComponent.ctrlRef, 'close').and.callThrough();
         });
 
         it('should test fake deletion that closes modal', fakeAsync(() => {
@@ -214,13 +199,13 @@ describe('CriticalConfirmationModalComponent', () => {
           component.callSubmitAction();
           expect(component.stopLoadingSpinner).not.toHaveBeenCalled();
           expect(component.hideModal).not.toHaveBeenCalled();
-          expect(mockComponent.ctrlRef.hide).not.toHaveBeenCalled();
+          expect(mockComponent.ctrlRef.close).not.toHaveBeenCalled();
           expect(component.submitAction).toHaveBeenCalled();
           expect(mockComponent.finished).toBe(undefined);
           // After deletionCall
           tick(2000);
           expect(component.hideModal).not.toHaveBeenCalled();
-          expect(mockComponent.ctrlRef.hide).toHaveBeenCalled();
+          expect(mockComponent.ctrlRef.close).toHaveBeenCalled();
           expect(mockComponent.finished).toEqual([6, 7, 8, 9]);
         }));
       });
index 5dfe0caee42c553c9be9ae81f8541161dab7dec3..a929b7dde86f5d77b0f2c51c90847396865096aa 100644 (file)
@@ -1,7 +1,7 @@
 import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
 import { FormControl, Validators } from '@angular/forms';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { Observable } from 'rxjs';
 
 import { CdFormGroup } from '../../forms/cd-form-group';
@@ -27,7 +27,7 @@ export class CriticalConfirmationModalComponent implements OnInit {
   childFormGroup: CdFormGroup;
   childFormGroupTemplate: TemplateRef<any>;
 
-  constructor(public modalRef: BsModalRef) {}
+  constructor(public activeModal: NgbActiveModal) {}
 
   ngOnInit() {
     const controls = {
@@ -54,7 +54,7 @@ export class CriticalConfirmationModalComponent implements OnInit {
   }
 
   hideModal() {
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 
   stopLoadingSpinner() {
index 2ccb7893f64b4d483d8be2e6b1bc02630754dbd8..f1f4b7f573f6a6ce1f70d2b30a6cea083bef47ea 100755 (executable)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container *ngIf="titleText"
                 class="modal-title">
     {{ titleText }}
@@ -64,7 +64,7 @@
                           (submitAction)="onSubmitForm(formGroup.value)">
           {{ submitButtonText }}
         </cd-submit-button>
-        <cd-back-button [back]="bsModalRef.hide"></cd-back-button>
+        <cd-back-button [back]="activeModal.close"></cd-back-button>
       </div>
     </form>
   </ng-container>
index 227076c1bdb0cc5a6e8662a9230c51303900c830..fbf10aa4594eeeca70fbd31bbaaaaf32c0422730 100755 (executable)
@@ -2,8 +2,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { ReactiveFormsModule, Validators } from '@angular/forms';
 import { RouterTestingModule } from '@angular/router/testing';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation';
-import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal';
 
 import {
   configureTestBed,
@@ -53,13 +53,12 @@ describe('InputModalComponent', () => {
 
   configureTestBed({
     imports: [
-      ModalModule.forRoot(),
       NgBootstrapFormValidationModule.forRoot(),
       RouterTestingModule,
       ReactiveFormsModule,
       SharedModule
     ],
-    providers: [i18nProviders, BsModalRef]
+    providers: [i18nProviders, NgbActiveModal]
   });
 
   beforeEach(() => {
index 7bc5d06b7caf534eeb29cd59e9ded44fc510d676..a4017941229092e3e8c9c8874718ee7790e7cec1 100755 (executable)
@@ -1,9 +1,9 @@
 import { Component, OnInit } from '@angular/core';
 import { FormControl, ValidatorFn, Validators } from '@angular/forms';
 
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import * as _ from 'lodash';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { CdFormBuilder } from '../../forms/cd-form-builder';
 import { CdFormGroup } from '../../forms/cd-form-group';
@@ -28,7 +28,7 @@ export class FormModalComponent implements OnInit {
   formGroup: CdFormGroup;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private formBuilder: CdFormBuilder,
     private formatter: FormatterService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
@@ -104,7 +104,7 @@ export class FormModalComponent implements OnInit {
         values[key] = this.formatter.toBytes(value);
       }
     });
-    this.bsModalRef.hide();
+    this.activeModal.close();
     if (_.isFunction(this.onSubmit)) {
       this.onSubmit(values);
     }
index a43ece29029c35467705a7b0968c08be05897e8d..86c55beff4f7c06562700812cc5a03a2a4f07fae 100644 (file)
@@ -1,6 +1,6 @@
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 
-import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed } from '../../../../testing/unit-test-helper';
 import { ModalComponent } from './modal.component';
@@ -10,7 +10,6 @@ describe('ModalComponent', () => {
   let fixture: ComponentFixture<ModalComponent>;
 
   configureTestBed({
-    imports: [ModalModule.forRoot()],
     declarations: [ModalComponent]
   });
 
@@ -34,9 +33,9 @@ describe('ModalComponent', () => {
   });
 
   it('should hide the modal', () => {
-    component.modalRef = new BsModalRef();
-    spyOn(component.modalRef, 'hide');
+    component.modalRef = new NgbActiveModal();
+    spyOn(component.modalRef, 'close');
     component.close();
-    expect(component.modalRef.hide).toHaveBeenCalled();
+    expect(component.modalRef.close).toHaveBeenCalled();
   });
 });
index 47cc5d74566836bbbc228fd29018621a6d09455d..730da6d62527b811a1056cdd79fc8351506d212a 100644 (file)
@@ -1,6 +1,6 @@
 import { Component, EventEmitter, Input, Output } from '@angular/core';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 @Component({
   selector: 'cd-modal',
@@ -9,7 +9,7 @@ import { BsModalRef } from 'ngx-bootstrap/modal';
 })
 export class ModalComponent {
   @Input()
-  modalRef: BsModalRef;
+  modalRef: NgbActiveModal;
 
   /**
    * Should be a function that is triggered when the modal is hidden.
@@ -18,9 +18,7 @@ export class ModalComponent {
   hide = new EventEmitter();
 
   close() {
-    if (this.modalRef) {
-      this.modalRef.hide();
-    }
+    this.modalRef?.close();
     this.hide.emit();
   }
 }
index a205f714eed2633cf56c1381aa86956381724db5..338be7df6dc19b781ba66ffa3e59df378d461f8e 100644 (file)
@@ -1,4 +1,4 @@
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>{{ actionDescription }} {{ itemDescription }}</ng-container>
 
@@ -7,7 +7,7 @@
       <cd-orchestrator-doc-panel></cd-orchestrator-doc-panel>
     </div>
     <div class="modal-footer">
-      <cd-back-button [back]="bsModalRef.hide"
+      <cd-back-button [back]="activeModal.close"
                       name="Close"
                       i18n-name>
       </cd-back-button>
index 49fe43853849bdc06e633a54099342276aecb56d..2bcf2ae317fff9f1bbd2fcb65e4754fa5b2976ed 100644 (file)
@@ -2,7 +2,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
 import { ComponentsModule } from '../components.module';
@@ -14,7 +14,7 @@ describe('OrchestratorDocModalComponent', () => {
 
   configureTestBed({
     imports: [ComponentsModule, HttpClientTestingModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
index e008edff634651bc2fcf9e12d461dd7f44d37824..d8fd210b8a2c0f8b2f34b7a056f534246f59bc47 100644 (file)
@@ -1,6 +1,6 @@
 import { Component } from '@angular/core';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 @Component({
   selector: 'cd-orchestrator-doc-modal',
@@ -11,9 +11,9 @@ export class OrchestratorDocModalComponent {
   actionDescription: string;
   itemDescription: string;
 
-  constructor(public bsModalRef: BsModalRef) {}
+  constructor(public activeModal: NgbActiveModal) {}
 
   onSubmit() {
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
index bb82707ab1a289da072c95fcb983a61b66379bf5..1ae3095a095f728f7a6b92f21e74df98eddb93dd 100644 (file)
@@ -1,7 +1,7 @@
 import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { TestBed } from '@angular/core/testing';
 
-import { BsModalService, ModalModule } from 'ngx-bootstrap/modal';
+import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
 
 import { configureTestBed } from '../../../testing/unit-test-helper';
 import { OrchestratorService } from '../api/orchestrator.service';
@@ -9,8 +9,8 @@ import { DepCheckerService } from './dep-checker.service';
 
 describe('DepCheckerService', () => {
   configureTestBed({
-    providers: [BsModalService, DepCheckerService, OrchestratorService],
-    imports: [HttpClientTestingModule, ModalModule.forRoot()]
+    providers: [DepCheckerService, OrchestratorService],
+    imports: [HttpClientTestingModule, NgbModalModule]
   });
 
   it('should be created', () => {
index 84a0dfa489c594fea07c93b270ca7f028f5f7d42..95cf292bcc1aec3b253a92cdc17ad0aa567d47d7 100644 (file)
@@ -1,15 +1,14 @@
 import { Injectable } from '@angular/core';
 
-import { BsModalService } from 'ngx-bootstrap/modal';
-
 import { OrchestratorService } from '../api/orchestrator.service';
 import { OrchestratorDocModalComponent } from '../components/orchestrator-doc-modal/orchestrator-doc-modal.component';
+import { ModalService } from './modal.service';
 
 @Injectable({
   providedIn: 'root'
 })
 export class DepCheckerService {
-  constructor(private orchService: OrchestratorService, private modalService: BsModalService) {}
+  constructor(private orchService: OrchestratorService, private modalService: ModalService) {}
 
   /**
    * Check if orchestrator is available. Display an information modal if not.
@@ -25,10 +24,8 @@ export class DepCheckerService {
         func();
       } else {
         this.modalService.show(OrchestratorDocModalComponent, {
-          initialState: {
-            actionDescription: actionDescription,
-            itemDescription: itemDescription
-          }
+          actionDescription: actionDescription,
+          itemDescription: itemDescription
         });
       }
     });
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts
new file mode 100644 (file)
index 0000000..2fb07e1
--- /dev/null
@@ -0,0 +1,59 @@
+import { Component } from '@angular/core';
+import { fakeAsync, TestBed, tick } from '@angular/core/testing';
+
+import { NgbActiveModal, NgbModal, NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
+
+import { configureTestBed } from '../../../testing/unit-test-helper';
+import { ModalService } from './modal.service';
+
+@Component({
+  template: ``
+})
+class MockComponent {
+  foo = '';
+
+  constructor(public activeModal: NgbActiveModal) {}
+}
+
+describe('ModalService', () => {
+  let service: ModalService;
+  let ngbModal: NgbModal;
+
+  configureTestBed({ declarations: [MockComponent], imports: [NgbModalModule] }, [MockComponent]);
+
+  beforeEach(() => {
+    service = TestBed.inject(ModalService);
+    ngbModal = TestBed.inject(NgbModal);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+
+  it('should call NgbModal.open when show is called', () => {
+    spyOn(ngbModal, 'open').and.callThrough();
+
+    const modaRef = service.show(MockComponent, { foo: 'bar' });
+
+    expect(ngbModal.open).toBeCalled();
+    expect(modaRef.componentInstance.foo).toBe('bar');
+    expect(modaRef.componentInstance.activeModal).toBeTruthy();
+  });
+
+  it('should call dismissAll and hasOpenModals', fakeAsync(() => {
+    spyOn(ngbModal, 'dismissAll').and.callThrough();
+    spyOn(ngbModal, 'hasOpenModals').and.callThrough();
+
+    expect(ngbModal.hasOpenModals()).toBeFalsy();
+
+    service.show(MockComponent, { foo: 'bar' });
+    expect(service.hasOpenModals()).toBeTruthy();
+
+    service.dismissAll();
+    tick();
+    expect(service.hasOpenModals()).toBeFalsy();
+
+    expect(ngbModal.dismissAll).toBeCalled();
+    expect(ngbModal.hasOpenModals).toBeCalled();
+  }));
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts
new file mode 100644 (file)
index 0000000..33ce8bd
--- /dev/null
@@ -0,0 +1,28 @@
+import { Injectable } from '@angular/core';
+
+import { NgbModal, NgbModalOptions, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class ModalService {
+  constructor(private modal: NgbModal) {}
+
+  show(component: any, initialState?: any, options?: NgbModalOptions): NgbModalRef {
+    const modalRef = this.modal.open(component, options);
+
+    if (initialState) {
+      Object.assign(modalRef.componentInstance, initialState);
+    }
+
+    return modalRef;
+  }
+
+  dismissAll() {
+    this.modal.dismissAll();
+  }
+
+  hasOpenModals() {
+    return this.modal.hasOpenModals();
+  }
+}
index 9ca18108182271129311cc63e64d3272eb1e4ed0..8b12c377a39b9be82ba90904dbbf0237e1caa903 100644 (file)
@@ -4,10 +4,9 @@ import { AbstractControl } from '@angular/forms';
 import { By } from '@angular/platform-browser';
 import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
 
-import { NgbNav, NgbNavItem } from '@ng-bootstrap/ng-bootstrap';
+import { NgbModal, NgbNav, NgbNavItem } from '@ng-bootstrap/ng-bootstrap';
 import { I18n } from '@ngx-translate/i18n-polyfill';
 import { configureTestSuite } from 'ng-bullet';
-import { BsModalRef } from 'ngx-bootstrap/modal';
 
 import { TableActionsComponent } from '../app/shared/datatable/table-actions/table-actions.component';
 import { Icons } from '../app/shared/enum/icons.enum';
@@ -180,21 +179,18 @@ export class FormHelper {
 }
 
 /**
- * Use this to mock 'ModalService.show' to make the embedded component with it's fixture usable
+ * Use this to mock 'modalService.open' to make the embedded component with it's fixture usable
  * in tests. The function gives back all needed parts including the modal reference.
  *
  * Please make sure to call this function *inside* your mock and return the reference at the end.
  */
 export function modalServiceShow(componentClass: Type<any>, modalConfig: any) {
-  const ref = new BsModalRef();
-  const fixture = TestBed.createComponent(componentClass);
-  let component = fixture.componentInstance;
-  if (modalConfig.initialState) {
-    component = Object.assign(component, modalConfig.initialState);
-  }
-  fixture.detectChanges();
-  ref.content = component;
-  return { ref, fixture, component };
+  const modal: NgbModal = TestBed.inject(NgbModal);
+  const modalRef = modal.open(componentClass);
+  if (modalConfig) {
+    Object.assign(modalRef.componentInstance, modalConfig);
+  }
+  return modalRef;
 }
 
 export class FixtureHelper {