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';
     NgbNavModule,
     BsDatepickerModule.forRoot(),
     NgbTooltipModule,
-    ModalModule.forRoot(),
     SharedModule,
     RouterModule,
     NgBootstrapFormValidationModule,
 
-<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>
 
 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 {
       ToastrModule.forRoot(),
       RouterTestingModule
     ],
-    providers: [i18nProviders, BsModalRef]
+    providers: [i18nProviders, NgbActiveModal]
   });
 
   beforeEach(() => {
 
 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';
 
   constructor(
     private authStorageService: AuthStorageService,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private iscsiService: IscsiService,
     private notificationService: NotificationService,
     private i18n: I18n
           NotificationType.success,
           this.i18n('Updated discovery authentication')
         );
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
       () => {
         this.discoveryForm.setErrors({ cdSubmitButton: true });
 
 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';
 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';
 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;
 
   constructor(
     private iscsiService: IscsiService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private rbdService: RbdService,
     private router: Router,
     private route: ActivatedRoute,
       target_controls_limits: this.target_controls_limits
     };
 
-    this.modalRef = this.modalService.show(IscsiTargetIqnSettingsModalComponent, { initialState });
+    this.modalRef = this.modalService.show(IscsiTargetIqnSettingsModalComponent, initialState);
   }
 
   imageSettingsModal(image: string) {
       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) {
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title">
     <ng-container i18n>Configure</ng-container> 
     <small>{{ image }}</small>
         <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>
 
 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';
   configureTestBed({
     declarations: [IscsiTargetImageSettingsModalComponent, IscsiSettingComponent],
     imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   settingsForm: CdFormGroup;
 
-  constructor(public modalRef: BsModalRef, public iscsiService: IscsiService) {}
+  constructor(public activeModal: NgbActiveModal, public iscsiService: IscsiService) {}
 
   ngOnInit() {
     const fg: Record<string, FormControl> = {
     this.imagesSettings[this.image][backstore] = settings;
     this.imagesSettings = { ...this.imagesSettings };
     this.control.updateValueAndValidity({ emitEvent: false });
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 }
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Advanced Settings</ng-container>
 
         <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>
 
 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';
   configureTestBed({
     declarations: [IscsiTargetIqnSettingsModalComponent, IscsiSettingComponent],
     imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   settingsForm: CdFormGroup;
 
-  constructor(public modalRef: BsModalRef, public iscsiService: IscsiService) {}
+  constructor(public activeModal: NgbActiveModal, public iscsiService: IscsiService) {}
 
   ngOnInit() {
     const fg: Record<string, FormControl> = {};
     });
 
     this.target_controls.setValue(settings);
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 
   getTargetControlLimits(setting: string) {
 
 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';
 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';
   available: boolean = undefined;
   columns: CdTableColumn[];
   docsUrl: string;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   permission: Permission;
   selection = new CdTableSelection();
   cephIscsiConfigVersion: number;
     private cephReleaseNamePipe: CephReleaseNamePipe,
     private notAvailablePipe: NotAvailablePipe,
     private summaryservice: SummaryService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     public actionLabels: ActionLabelsI18n
   ) {
     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);
   }
 }
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Create Bootstrap Token</ng-container>
 
       </div>
 
       <div class="modal-footer">
-        <cd-back-button [back]="modalRef.hide"
+        <cd-back-button [back]="activeModal.close"
                         name="Close"
                         i18n-name>
         </cd-back-button>
 
 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';
 
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
   describe('generate token', () => {
     beforeEach(() => {
       spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
       fixture.detectChanges();
     });
 
 
 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';
 
   createBootstrapForm: CdFormGroup;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Import Bootstrap Token</ng-container>
 
         <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>
 
 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';
 
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
   describe('import token', () => {
     beforeEach(() => {
       spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.modalRef, 'hide').and.callThrough();
+      spyOn(component.activeModal, 'close').and.callThrough();
       fixture.detectChanges();
     });
 
 
 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';
 
   ];
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
       error: finishHandler,
       complete: () => {
         finishHandler();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Edit site name</ng-container>
 
         <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>
 
 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';
 
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
     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', () => {
 
 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';
   editSiteNameForm: CdFormGroup;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
       error: () => this.editSiteNameForm.setErrors({ cdSubmitButton: true }),
       complete: () => {
         this.rbdMirroringService.refresh();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
 
 
 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';
     FormsModule,
     ReactiveFormsModule,
     NgbProgressbarModule,
-    ModalModule.forRoot(),
     NgBootstrapFormValidationModule
   ],
   declarations: [
 
 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';
 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';
   permission: Permission;
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   peersExist = true;
   siteName: any;
   status: ViewCacheStatus;
   constructor(
     private authStorageService: AuthStorageService,
     private rbdMirroringService: RbdMirroringService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n
   ) {
     this.permission = this.authStorageService.getPermissions().rbdMirroring;
     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);
   }
 }
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Edit pool mirror mode</ng-container>
 
         <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>
 
 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';
 
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
   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', () => {
 
 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';
   ];
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
       error: () => this.editModeForm.setErrors({ cdSubmitButton: true }),
       complete: () => {
         this.rbdMirroringService.refresh();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
 
-<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>
         <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>
 
 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';
 
       SharedModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
       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', () => {
 
       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', () => {
 
 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';
   response: PoolEditPeerResponseModel;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdMirroringService: RbdMirroringService,
     private taskWrapper: TaskWrapperService
   ) {
       error: () => this.editPeerForm.setErrors({ cdSubmitButton: true }),
       complete: () => {
         this.rbdMirroringService.refresh();
-        this.modalRef.hide();
+        this.activeModal.close();
       }
     });
   }
 
 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';
 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';
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   data: [];
   columns: {};
   constructor(
     private authStorageService: AuthStorageService,
     private rbdMirroringService: RbdMirroringService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     private i18n: I18n
   ) {
     const initialState = {
       poolName: this.selection.first().name
     };
-    this.modalRef = this.modalService.show(PoolEditModeModalComponent, { initialState });
+    this.modalRef = this.modalService.show(PoolEditModeModalComponent, initialState);
   }
 
   editPeersModal(mode: string) {
     if (mode === 'edit') {
       initialState['peerUUID'] = this.getPeerUUID();
     }
-    this.modalRef = this.modalService.show(PoolEditPeerModalComponent, { initialState });
+    this.modalRef = this.modalService.show(PoolEditPeerModalComponent, initialState);
   }
 
   deletePeersModal() {
     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();
+              }
+            });
+        })
     });
   }
 
 
 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';
 
       BrowserAnimationsModule,
       SharedModule,
       NgbNavModule,
-      ModalModule.forRoot(),
       NgbTooltipModule,
       ToastrModule.forRoot(),
       RouterTestingModule,
 
 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';
 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';
   viewCacheStatusList: any[];
   selection = new CdTableSelection();
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   builders = {
     'rbd/create': (metadata: object) =>
     private rbdService: RbdService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
     private dimlessPipe: DimlessPipe,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     private taskListService: TaskListService,
     private i18n: I18n,
     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)
+        })
     });
   }
 
       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) {
       })
       .subscribe({
         complete: () => {
-          this.modalRef.hide();
+          this.modalRef.close();
         }
       });
   }
       }
     };
 
-    this.modalRef = this.modalService.show(ConfirmationModalComponent, { initialState });
+    this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState);
   }
 
   hasSnapshots() {
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Create Namespace</ng-container>
 
         <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>
 
 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';
       RouterTestingModule
     ],
     declarations: [RbdNamespaceFormModalComponent],
-    providers: [BsModalRef, BsModalService, AuthStorageService, i18nProviders]
+    providers: [NgbActiveModal, AuthStorageService, i18nProviders]
   });
 
   beforeEach(() => {
 
   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';
   public onSubmit: Subject<void>;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private notificationService: NotificationService,
     private poolService: PoolService,
             namespace: namespace
           })
         );
-        this.modalRef.hide();
+        this.activeModal.close();
         this.onSubmit.next();
       })
       .catch(() => {
 
 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';
 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';
 export class RbdNamespaceListComponent implements OnInit {
   columns: CdTableColumn[];
   namespaces: any;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   permission: Permission;
   selection = new CdTableSelection();
   tableActions: CdTableAction[];
     private authStorageService: AuthStorageService,
     private rbdService: RbdService,
     private poolService: PoolService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
 
   createModal() {
     this.modalRef = this.modalService.show(RbdNamespaceFormModalComponent);
-    this.modalRef.content.onSubmit.subscribe(() => {
+    this.modalRef.componentInstance.onSubmit.subscribe(() => {
       this.refresh();
     });
   }
     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();
+          }
+        )
     });
   }
 
 
-<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>
 
                           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>
 
 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';
       RouterTestingModule
     ],
     declarations: [RbdSnapshotFormModalComponent],
-    providers: [BsModalRef, BsModalService, AuthStorageService, i18nProviders]
+    providers: [NgbActiveModal, AuthStorageService, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
   public onSubmit: Subject<string>;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private rbdService: RbdService,
     private taskManagerService: TaskManagerService,
     private notificationService: NotificationService,
             this.notificationService.notifyTask(asyncFinishedTask);
           }
         );
-        this.modalRef.hide();
+        this.activeModal.close();
         this.onSubmit.next(this.snapName);
       })
       .catch(() => {
             this.notificationService.notifyTask(asyncFinishedTask);
           }
         );
-        this.modalRef.hide();
+        this.activeModal.close();
         this.onSubmit.next(snapshotName);
       })
       .catch(() => {
 
 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';
 
 } 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';
     }
   };
 
-  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);
     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);
       authStorageService.set('user', '', { 'rbd-image': ['create', 'read', 'update', 'delete'] });
       component = new RbdSnapshotListComponent(
         authStorageService,
-        null,
+        modalService,
         null,
         null,
         rbdService,
       );
       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);
     }));
     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,
           TestBed.inject(I18n),
           TestBed.inject(ActionLabelsI18n)
         );
-        ref.content.onSubmit = new Subject();
+        ref.componentInstance.onSubmit = new Subject();
         return ref;
       });
     });
     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:]+$`)
       );
     });
 
 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';
 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';
 
   columns: CdTableColumn[];
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   builders = {
     'rbd/snap/create': (metadata: any) => {
 
   constructor(
     private authStorageService: AuthStorageService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
     private cdDatePipe: CdDatePipe,
     private rbdService: RbdService,
 
   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 = {
         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,
         );
       })
       .catch(() => {
-        this.modalRef.content.stopLoadingSpinner();
+        this.modalRef.componentInstance.stopLoadingSpinner();
       });
   }
 
       }
     };
 
-    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)
     });
   }
 
 
 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';
 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';
   columns: CdTableColumn[];
   executingTasks: ExecutingTask[] = [];
   images: any;
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   permission: Permission;
   retries: number;
   selection = new CdTableSelection();
   constructor(
     private authStorageService: AuthStorageService,
     private rbdService: RbdService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private cdDatePipe: CdDatePipe,
     private taskListService: TaskListService,
     private taskWrapper: TaskWrapperService,
       imageId: this.selection.first().id
     };
 
-    this.modalRef = this.modalService.show(RbdTrashRestoreModalComponent, { initialState });
+    this.modalRef = this.modalService.show(RbdTrashRestoreModalComponent, initialState);
   }
 
   deleteModal() {
     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)
+        })
     });
   }
 
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Move an image to trash</ng-container>
 
         <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>
 
 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';
       BsDatepickerModule.forRoot()
     ],
     declarations: [RbdTrashMoveModalComponent],
-    providers: [BsModalRef, BsModalService, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
     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', () => {
 
 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';
 
   constructor(
     private rbdService: RbdService,
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private fb: CdFormBuilder,
     private taskWrapper: TaskWrapperService
   ) {
       })
       .subscribe({
         complete: () => {
-          this.modalRef.hide();
+          this.activeModal.close();
         }
       });
   }
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Purge Trash</ng-container>
 
                           [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>
 
 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';
       RouterTestingModule
     ],
     declarations: [RbdTrashPurgeModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
   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();
 
     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);
     });
   });
 });
 
 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';
   constructor(
     private authStorageService: AuthStorageService,
     private rbdService: RbdService,
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private fb: CdFormBuilder,
     private poolService: PoolService,
     private taskWrapper: TaskWrapperService
           this.purgeForm.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.modalRef.hide();
+          this.activeModal.close();
         }
       });
   }
 
-<cd-modal [modalRef]="modalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container i18n
                 class="modal-title">Restore Image</ng-container>
 
         <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>
 
 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';
       SharedModule,
       RouterTestingModule
     ],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
   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();
 
     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);
     });
   });
 });
 
 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';
 
   constructor(
     private rbdService: RbdService,
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private fb: CdFormBuilder,
     private taskWrapper: TaskWrapperService
   ) {}
           this.restoreForm.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.modalRef.hide();
+          this.activeModal.close();
         }
       });
   }
 
 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';
 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({
 
   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,
     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();
       }
     );
   }
   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)
     });
   }
 }
 
 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';
 
 } 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';
   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';
   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 = {
     },
     modalShow: (comp: Type<any>, init: any): any => {
       modal = modalServiceShow(comp, init);
-      return modal.ref;
+      return modal;
     },
     getNodeById: (path: string) => {
       return mockLib.useNode(path);
     },
     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
       });
     },
     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: (
       max: number,
       errors?: { [key: string]: string }
     ) => {
-      expect(modalShowSpy).toHaveBeenCalledWith(FormModalComponent, {
-        initialState: expect.objectContaining({
+      expect(modalShowSpy).toHaveBeenCalledWith(
+        FormModalComponent,
+        expect.objectContaining({
           fields: [
             {
               type,
             }
           ]
         })
-      });
+      );
       if (type === 'binary') {
         expect(minBinaryValidator).toHaveBeenCalledWith(0);
         expect(maxBinaryValidator).toHaveBeenCalledWith(max);
     }
   };
 
-  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;
     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);
 
 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,
 } 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';
 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 {
   @Input()
   id: number;
 
-  private modalRef: BsModalRef;
+  private modalRef: NgbModalRef;
   private dirs: CephfsDir[];
   private nodeIds: { [path: string]: CephfsDir };
   private requestedPaths: string[];
 
   constructor(
     private authStorageService: AuthStorageService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private cephfsService: CephfsService,
     private cdDatePipe: CdDatePipe,
     private i18n: I18n,
     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)
     });
   }
 
     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())
     });
   }
 
     // 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();
+        });
       }
     });
   }
 
   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()
     });
   }
 
         );
       });
     });
-    this.modalRef.hide();
+    this.modalRef.close();
     this.forceDirRefresh();
   }
 
 
 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';
     FormsModule,
     ReactiveFormsModule,
     BsDatepickerModule.forRoot(),
-    ModalModule.forRoot(),
     NgbTooltipModule,
     MgrModulesModule,
     NgbTypeaheadModule,
 
 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';
 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';
   cdParams = { fromLink: '/hosts' };
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   constructor(
     private authStorageService: AuthStorageService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     private actionLabels: ActionLabelsI18n,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
     private router: Router,
     private depCheckerService: DepCheckerService,
   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)
+        })
     });
   }
 
 
 
 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';
 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';
 
     private authStorageService: AuthStorageService,
     private dimlessBinary: DimlessBinaryPipe,
     private i18n: I18n,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private orchService: OrchestratorService
   ) {}
     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
+            })
+          );
+        });
       }
     });
   }
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>OSD creation preview</ng-container>
 
       <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>
 
 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';
       RouterTestingModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, i18nProviders],
+    providers: [NgbActiveModal, i18nProviders],
     declarations: [OsdCreationPreviewModalComponent]
   });
 
 
 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';
   formGroup: CdFormGroup;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     public actionLabels: ActionLabelsI18n,
     private formBuilder: CdFormBuilder,
     private osdService: OsdService,
         },
         complete: () => {
           this.submitAction.emit();
-          this.bsModalRef.hide();
+          this.activeModal.close();
         }
       });
   }
 
 
 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';
     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();
     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;
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>{{ deviceType }} devices</ng-container>
 
         <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>
 
 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';
       RouterTestingModule,
       ToastrModule.forRoot()
     ],
-    providers: [BsModalRef, i18nProviders],
+    providers: [NgbActiveModal, i18nProviders],
     declarations: [OsdDevicesSelectionModalComponent, InventoryDevicesComponent]
   });
 
 
 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';
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     public actionLabels: ActionLabelsI18n
   ) {
     this.action = actionLabels.ADD;
 
   onSubmit() {
     this.submitAction.emit(this.event);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Cluster-wide OSD Flags</ng-container>
 
                           (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>
 
 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';
   configureTestBed({
     imports: [
       ReactiveFormsModule,
-      ModalModule.forRoot(),
       SharedModule,
       HttpClientTestingModule,
       RouterTestingModule,
       ToastrModule.forRoot()
     ],
     declarations: [OsdFlagsModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [i18nProviders, NgbActiveModal]
   });
 
   beforeEach(() => {
   describe('test submitAction', function () {
     let notificationType: NotificationType;
     let notificationService: NotificationService;
-    let bsModalRef: BsModalRef;
+    let bsModalRef: NgbActiveModal;
 
     beforeEach(() => {
       notificationService = TestBed.inject(NotificationService);
         notificationType = type;
       });
 
-      bsModalRef = TestBed.inject(BsModalRef);
-      spyOn(bsModalRef, 'hide').and.callThrough();
+      bsModalRef = TestBed.inject(NgbActiveModal);
+      spyOn(bsModalRef, 'close').and.callThrough();
       component.unknownFlags = ['foo'];
     });
 
       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', () => {
       req.flush([], { status: 500, statusText: 'failure' });
 
       expect(notificationService.show).toHaveBeenCalledTimes(0);
-      expect(component.bsModalRef.hide).toHaveBeenCalledTimes(1);
+      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
     });
   });
 });
 
 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';
   unknownFlags: string[] = [];
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private osdService: OsdService,
     private notificationService: NotificationService,
     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();
       }
     );
   }
 
 
 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';
 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';
     private i18n: I18n,
     private orchService: OrchestratorService,
     private router: Router,
-    private bsModalService: BsModalService
+    private modalService: ModalService
   ) {
     super();
     this.resource = this.i18n('OSDs');
     // 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;
 
 
 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';
 
 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';
     providers: [
       { provide: AuthStorageService, useValue: fakeAuthStorageService },
       TableActionsComponent,
-      BsModalService,
+      ModalService,
       i18nProviders
     ]
   });
     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', () => {
     ): 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);
 
 
 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';
 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';
 
   permissions: Permissions;
   tableActions: CdTableAction[];
-  bsModalRef: BsModalRef;
+  bsModalRef: NgbModalRef;
   columns: CdTableColumn[];
   clusterWideActions: CdTableAction[];
   icons = Icons;
     private authStorageService: AuthStorageService,
     private osdService: OsdService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     private router: Router,
     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();
+        });
       }
     });
   }
       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
     });
   }
 
   ): 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()
-              );
-            }
           }
         }
       });
   }
 
   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' });
   }
 }
 
-<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)="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>
 
 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';
 
   configureTestBed({
     imports: [
       HttpClientTestingModule,
-      ModalModule.forRoot(),
       ReactiveFormsModule,
       RouterTestingModule,
       SharedModule,
       ToastrModule.forRoot()
     ],
     declarations: [OsdPgScrubModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
   advancedEnabled = false;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private notificationService: NotificationService,
     private i18n: I18n,
           NotificationType.success,
           this.i18n('Updated PG scrub options')
         );
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
       () => {
-        this.bsModalRef.hide();
+        this.activeModal.close();
       }
     );
   }
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>OSD Recovery Priority</ng-container>
 
                           (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>
 
 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';
 
   configureTestBed({
     imports: [
       HttpClientTestingModule,
-      ModalModule.forRoot(),
       ReactiveFormsModule,
       RouterTestingModule,
       SharedModule,
       ToastrModule.forRoot()
     ],
     declarations: [OsdRecvSpeedModalComponent],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   let configOptions: any[] = [];
 
 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';
   priorityAttrs = {};
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private authStorageService: AuthStorageService,
     private configService: ConfigurationService,
     private notificationService: NotificationService,
             value: this.osdRecvSpeedForm.getValue('priority')
           })
         );
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
       () => {
-        this.bsModalRef.hide();
+        this.activeModal.close();
       }
     );
   }
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Reweight OSD: {{ osdId }}</ng-container>
 
                           [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>
 
 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';
       SubmitButtonComponent,
       BackButtonComponent
     ],
-    providers: [OsdService, BsModalRef, CdFormBuilder, i18nProviders]
+    providers: [OsdService, NgbActiveModal, CdFormBuilder, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
   reweightForm: CdFormGroup;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private osdService: OsdService,
     private fb: CdFormBuilder
   ) {}
   reweight() {
     this.osdService
       .reweight(this.osdId, this.reweightForm.value.weight)
-      .subscribe(() => this.bsModalRef.hide());
+      .subscribe(() => this.activeModal.close());
   }
 }
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>OSDs {deep, select, 1 {Deep }}Scrub</ng-container>
 
         <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>
 
 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';
     declarations: [OsdScrubModalComponent, JoinPipe],
     schemas: [NO_ERRORS_SCHEMA],
     providers: [
-      BsModalRef,
+      NgbActiveModal,
       JoinPipe,
       { provide: OsdService, useValue: fakeService },
       { provide: NotificationService, useValue: fakeService },
 
 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';
   selected: any[] = [];
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private osdService: OsdService,
     private notificationService: NotificationService,
     private i18n: I18n,
           })
         );
 
-        this.bsModalRef.hide();
+        this.activeModal.close();
       },
-      () => this.bsModalRef.hide()
+      () => this.activeModal.close()
     );
   }
 }
 
 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';
 
 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';
       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]);
             },
 
 
 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 {
 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';
     private notificationService: NotificationService,
     private route: ActivatedRoute,
     private timeDiff: TimeDiffService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private silenceMatcher: PrometheusSilenceMatcherService,
     private actionLabels: ActionLabelsI18n,
     private succeededLabels: SucceededActionLabelsI18n
   }
 
   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);
     });
   }
 
 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';
 
 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';
     imports: [
       BrowserAnimationsModule,
       SharedModule,
-      ModalModule.forRoot(),
       ToastrModule.forRoot(),
       RouterTestingModule,
       HttpClientTestingModule
 
     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();
     };
       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)
         };
       });
     });
 
 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';
 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';
 
   tableActions: CdTableAction[];
   permission: Permission;
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   customCss = {
     'badge badge-danger': 'active',
     'badge badge-warning': 'pending',
     private i18n: I18n,
     private cdDatePipe: CdDatePipe,
     private prometheusService: PrometheusService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private urlBuilder: URLBuilderService,
     private actionLabels: ActionLabelsI18n,
     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();
+            }
+          );
+        })
     });
   }
 }
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>Matcher</ng-container>
 
                           [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>
 
 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,
       RouterTestingModule,
       ReactiveFormsModule
     ],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   constructor(
     private formBuilder: CdFormBuilder,
     private silenceMatcher: PrometheusSilenceMatcherService,
-    public bsModalRef: BsModalRef
+    public activeModal: NgbActiveModal
   ) {
     this.createForm();
     this.subscribeToChanges();
 
   onSubmit() {
     this.submitAction.emit(this.form.value);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 
   search = (text$: Observable<string>) => {
 
 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';
 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';
 
   tableActions: CdTableAction[];
   isDefaultCluster = false;
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   builders = {
     'nfs/create': (metadata: any) => {
   constructor(
     private authStorageService: AuthStorageService,
     private i18n: I18n,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private nfsService: NfsService,
     private taskListService: TaskListService,
     private taskWrapper: TaskWrapperService,
     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)
+        })
     });
   }
 }
 
-<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>
 
 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';
 
       PoolModule,
       NgBootstrapFormValidationModule.forRoot()
     ],
-    providers: [CrushRuleService, BsModalRef, i18nProviders]
+    providers: [CrushRuleService, NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private taskWrapper: TaskWrapperService,
     private crushRuleService: CrushRuleService,
     private i18n: I18n,
           this.form.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.bsModalRef.hide();
+          this.activeModal.close();
           this.submitAction.emit(rule);
         }
       });
 
-<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>
 
 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';
 
       PoolModule,
       NgBootstrapFormValidationModule.forRoot()
     ],
-    providers: [ErasureCodeProfileService, BsModalRef, i18nProviders]
+    providers: [ErasureCodeProfileService, NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private taskWrapper: TaskWrapperService,
     private ecpService: ErasureCodeProfileService,
     private i18n: I18n,
           this.form.setErrors({ cdSubmitButton: true });
         },
         complete: () => {
-          this.bsModalRef.hide();
+          this.activeModal.close();
           this.submitAction.emit(profile);
         }
       });
 
 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';
 
 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';
 
   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;
 
     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 })
           }
         };
       };
 
       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
             };
           }
         );
 
         it('should hide the tooltip when clicking on add', () => {
           modalSpy.and.callFake((): any => ({
-            content: {
+            componentInstance: {
               submitAction: of('someRule')
             }
           }));
       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 })
           }
         };
       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) => {
 
       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) => {
 
         it('should hide the tooltip when clicking on add', () => {
           modalSpy.and.callFake((): any => ({
-            content: {
+            componentInstance: {
               submitAction: of('someProfile')
             }
           }));
 
 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';
 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';
     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,
 
   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);
     });
   }
     }
     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
+        });
       }
     });
   }
 
 
 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';
 
 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';
 
     const callDeletion = () => {
       component.deletePoolModal();
-      const deletion: CriticalConfirmationModalComponent = component.modalRef.content;
+      const deletion: CriticalConfirmationModalComponent = component.modalRef.componentInstance;
       deletion.submitActionObservable();
     };
 
     };
 
     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();
 
 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';
 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';
   pools: Pool[];
   columns: CdTableColumn[];
   selection = new CdTableSelection();
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
   executingTasks: ExecutingTask[] = [];
   permissions: Permissions;
   tableActions: CdTableAction[];
     private taskWrapper: TaskWrapperService,
     private authStorageService: AuthStorageService,
     private taskListService: TaskListService,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private pgCategoryService: PgCategoryService,
     private dimlessPipe: DimlessPipe,
   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)
+        })
     });
   }
 
 
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
-import { ModalModule } from 'ngx-bootstrap/modal';
 import { of } from 'rxjs';
 
 import {
     imports: [
       BrowserAnimationsModule,
       RouterTestingModule,
-      ModalModule.forRoot(),
       SharedModule,
       NgbNavModule,
       HttpClientTestingModule
 
 
 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';
 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';
     private dimlessBinaryPipe: DimlessBinaryPipe,
     private dimlessPipe: DimlessPipe,
     private rgwBucketService: RgwBucketService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     public actionLabels: ActionLabelsI18n,
   }
 
   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();
+            }
           });
-        }
+        });
       }
     });
   }
 
-<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]="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>
 
 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';
   configureTestBed({
     declarations: [RgwUserCapabilityModalComponent],
     imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
   ) {
   onSubmit() {
     const capability: RgwUserCapability = this.formGroup.value;
     this.submitAction.emit(capability);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
 
 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';
   configureTestBed({
     declarations: [RgwUserDetailsComponent],
     imports: [BrowserAnimationsModule, HttpClientTestingModule, SharedModule, NgbNavModule],
-    providers: [BsModalService, i18nProviders]
+    providers: [i18nProviders]
   });
 
   beforeEach(() => {
 
 
 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';
 
   constructor(
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n
   ) {}
 
 
   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;
     }
   }
 
 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';
 
       ToastrModule.forRoot(),
       NgbTooltipModule
     ],
-    providers: [BsModalService, i18nProviders]
+    providers: [i18nProviders]
   });
 
   beforeEach(() => {
 
 
 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';
 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';
     private route: ActivatedRoute,
     private router: Router,
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private notificationService: NotificationService,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
    */
   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);
     });
   }
    * @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);
       });
     }
    * @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);
   }
 
   /**
    * @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);
     });
   }
 
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
-import { ModalModule } from 'ngx-bootstrap/modal';
-
 import {
   configureTestBed,
   i18nProviders,
 
   configureTestBed({
     declarations: [RgwUserListComponent],
-    imports: [
-      BrowserAnimationsModule,
-      RouterTestingModule,
-      HttpClientTestingModule,
-      ModalModule.forRoot(),
-      SharedModule
-    ],
+    imports: [BrowserAnimationsModule, RouterTestingModule, HttpClientTestingModule, SharedModule],
     schemas: [NO_ERRORS_SCHEMA],
     providers: i18nProviders
   });
 
 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';
 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';
   constructor(
     private authStorageService: AuthStorageService,
     private rgwUserService: RgwUserService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private i18n: I18n,
     private urlBuilder: URLBuilderService,
     public actionLabels: ActionLabelsI18n,
   }
 
   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();
+            }
           });
-        }
+        });
       }
     });
   }
 
-<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>
 
 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';
   configureTestBed({
     declarations: [RgwUserS3KeyModalComponent],
     imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
   ) {
   onSubmit() {
     const key: RgwUserS3Key = this.formGroup.value;
     this.submitAction.emit(key);
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
 
         <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>
 
 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';
   configureTestBed({
     declarations: [RgwUserSubuserModalComponent],
     imports: [ReactiveFormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   constructor(
     private formBuilder: CdFormBuilder,
-    public bsModalRef: BsModalRef,
+    public bsModalRef: NgbActiveModal,
     private i18n: I18n,
     private actionLabels: ActionLabelsI18n
   ) {
     subuser.generate_secret = values.generate_secret;
     subuser.secret_key = values.secret_key;
     this.submitAction.emit(subuser);
-    this.bsModalRef.hide();
+    this.bsModalRef.close();
   }
 }
 
-<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>
     </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>
 
 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';
   configureTestBed({
     declarations: [RgwUserSwiftKeyModalComponent],
     imports: [ToastrModule.forRoot(), FormsModule, SharedModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 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';
 
   action: string;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private i18n: I18n,
     public actionLabels: ActionLabelsI18n
   ) {
 
 
 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';
     ReactiveFormsModule,
     PerformanceCounterModule,
     NgbNavModule,
-    ModalModule.forRoot(),
     RouterModule,
     NgBootstrapFormValidationModule,
     NgbTooltipModule
 
   });
 
   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();
   });
 });
 
 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',
   constructor(
     private authService: AuthService,
     private authStorageService: AuthStorageService,
-    private bsModalService: BsModalService,
+    private modalService: ModalService,
     private router: Router
   ) {}
 
       // 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) {
 
 
 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';
   @ViewChild('cellPermissionCheckboxTpl', { static: true })
   cellPermissionCheckboxTpl: TemplateRef<any>;
 
-  modalRef: BsModalRef;
-
   roleForm: CdFormGroup;
   response: RoleFormModel;
 
 
 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';
 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';
 
   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,
     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();
       }
     );
   }
   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']
+            })
+          );
+        });
       }
     });
   }
 
 
 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';
 
 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';
   let fixture: ComponentFixture<UserFormComponent>;
   let httpTesting: HttpTestingController;
   let userService: UserService;
-  let modalService: BsModalService;
+  let modalService: ModalService;
   let router: Router;
   let formHelper: FormHelper;
 
     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();
     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();
 
 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';
 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';
   @ViewChild('removeSelfUserReadUpdatePermissionTpl', { static: true })
   removeSelfUserReadUpdatePermissionTpl: TemplateRef<any>;
 
-  modalRef: BsModalRef;
+  modalRef: NgbModalRef;
 
   userForm: CdFormGroup;
   response: UserFormModel;
     private authStorageService: AuthStorageService,
     private route: ActivatedRoute,
     public router: Router,
-    private modalService: BsModalService,
+    private modalService: ModalService,
     private roleService: RoleService,
     private userService: UserService,
     private notificationService: NotificationService,
         buttonText: this.i18n('Continue'),
         bodyTpl: this.removeSelfUserReadUpdatePermissionTpl,
         onSubmit: () => {
-          this.modalRef.hide();
+          this.modalRef.close();
           this.doEditAction();
         },
         onCancel: () => {
           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();
     }
 
 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';
 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';
 
   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,
     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();
       }
     );
   }
       );
       return;
     }
+
     this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, {
-      initialState: {
-        itemDescription: 'User',
-        itemNames: [username],
-        submitAction: () => this.deleteUser(username)
-      }
+      itemDescription: 'User',
+      itemNames: [username],
+      submitAction: () => this.deleteUser(username)
     });
   }
 }
 
     <button type="button"
             class="close float-right"
             aria-label="Close"
-            (click)="modalRef.hide()">
+            (click)="activeModal.close()">
       <span aria-hidden="true">×</span>
     </button>
   </div>
 
 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';
   configureTestBed({
     imports: [SharedModule, HttpClientTestingModule],
     declarations: [AboutComponent],
-    providers: [BsModalRef, { provide: SummaryService, useClass: SummaryServiceMock }]
+    providers: [NgbActiveModal, { provide: SummaryService, useClass: SummaryServiceMock }]
   });
 
   beforeEach(() => {
 
 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';
   copyright: string;
 
   constructor(
-    public modalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private summaryService: SummaryService,
     private userService: UserService,
     private authStorageService: AuthStorageService
 
 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';
 
   @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
   ) {}
 
   }
 
   openAboutModal() {
-    this.modalRef = this.modalService.show(AboutComponent);
-    this.modalRef.setClass('modal-lg');
+    this.modalRef = this.modalService.show(AboutComponent, null, { size: 'lg' });
   }
 
   goToApiDocs() {
 
 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';
     ChartsModule,
     ReactiveFormsModule,
     PipesModule,
-    ModalModule.forRoot(),
     DirectivesModule,
     NgbDropdownModule,
     NgBootstrapFormValidationModule,
 
 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';
 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',
           description: 'String based description.',
           onSubmit: () => {
             this.returnValue = 'The submit action has to hide manually.';
-            this.modalRef.hide();
           }
         },
         extendBaseState
       )
-    });
+    );
   }
 
   basicModal() {
   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({
       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(() => {
     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;
     });
   });
 
   describe('basics', () => {
     beforeEach(() => {
       mockComponent.basicModal();
-      spyOn(mockComponent.modalRef, 'hide').and.callFake(hide);
+      spyOn(component, 'onSubmit').and.callThrough();
     });
 
     it('should show the correct title', () => {
         '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);
     });
 
       );
     });
   });
-
-  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);
-    });
-  });
 });
 
 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',
   // 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() {
   }
 
   ngOnDestroy() {
-    this.onHide.unsubscribe();
+    if (this.onCancel && this.canceled) {
+      this.onCancel();
+    }
   }
 
   cancel() {
     this.canceled = true;
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 
   stopLoadingSpinner() {
 
 <cd-modal #modal
-          [modalRef]="modalRef">
+          [modalRef]="activeModal">
   <ng-container class="modal-title">
     <ng-container *ngTemplateOutlet="deletionHeading"></ng-container>
   </ng-container>
                           (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>
 
 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';
   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
     });
   }
 
   fakeDeleteController() {
     observableTimer(100).subscribe(() => {
       this.finish();
-      this.ctrlRef.hide();
+      this.ctrlRef.close();
     });
   }
 }
   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();
     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,
       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', () => {
       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(() => {
           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]);
         }));
       });
 
 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';
   childFormGroup: CdFormGroup;
   childFormGroupTemplate: TemplateRef<any>;
 
-  constructor(public modalRef: BsModalRef) {}
+  constructor(public activeModal: NgbActiveModal) {}
 
   ngOnInit() {
     const controls = {
   }
 
   hideModal() {
-    this.modalRef.hide();
+    this.activeModal.close();
   }
 
   stopLoadingSpinner() {
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container *ngIf="titleText"
                 class="modal-title">
     {{ titleText }}
                           (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>
 
 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,
 
   configureTestBed({
     imports: [
-      ModalModule.forRoot(),
       NgBootstrapFormValidationModule.forRoot(),
       RouterTestingModule,
       ReactiveFormsModule,
       SharedModule
     ],
-    providers: [i18nProviders, BsModalRef]
+    providers: [i18nProviders, NgbActiveModal]
   });
 
   beforeEach(() => {
 
 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';
   formGroup: CdFormGroup;
 
   constructor(
-    public bsModalRef: BsModalRef,
+    public activeModal: NgbActiveModal,
     private formBuilder: CdFormBuilder,
     private formatter: FormatterService,
     private dimlessBinaryPipe: DimlessBinaryPipe,
         values[key] = this.formatter.toBytes(value);
       }
     });
-    this.bsModalRef.hide();
+    this.activeModal.close();
     if (_.isFunction(this.onSubmit)) {
       this.onSubmit(values);
     }
 
   overflow-y: auto;
   overflow-x: hidden;
 }
+
+button.close {
+  outline: none;
+}
 
 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';
   let fixture: ComponentFixture<ModalComponent>;
 
   configureTestBed({
-    imports: [ModalModule.forRoot()],
     declarations: [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();
   });
 });
 
 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',
 })
 export class ModalComponent {
   @Input()
-  modalRef: BsModalRef;
+  modalRef: NgbActiveModal;
 
   /**
    * Should be a function that is triggered when the modal is hidden.
   hide = new EventEmitter();
 
   close() {
-    if (this.modalRef) {
-      this.modalRef.hide();
-    }
+    this.modalRef?.close();
     this.hide.emit();
   }
 }
 
-<cd-modal [modalRef]="bsModalRef">
+<cd-modal [modalRef]="activeModal">
   <ng-container class="modal-title"
                 i18n>{{ actionDescription }} {{ itemDescription }}</ng-container>
 
       <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>
 
 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';
 
   configureTestBed({
     imports: [ComponentsModule, HttpClientTestingModule, RouterTestingModule],
-    providers: [BsModalRef, i18nProviders]
+    providers: [NgbActiveModal, i18nProviders]
   });
 
   beforeEach(() => {
 
 import { Component } from '@angular/core';
 
-import { BsModalRef } from 'ngx-bootstrap/modal';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
 
 @Component({
   selector: 'cd-orchestrator-doc-modal',
   actionDescription: string;
   itemDescription: string;
 
-  constructor(public bsModalRef: BsModalRef) {}
+  constructor(public activeModal: NgbActiveModal) {}
 
   onSubmit() {
-    this.bsModalRef.hide();
+    this.activeModal.close();
   }
 }
 
 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';
 
 describe('DepCheckerService', () => {
   configureTestBed({
-    providers: [BsModalService, DepCheckerService, OrchestratorService],
-    imports: [HttpClientTestingModule, ModalModule.forRoot()]
+    providers: [DepCheckerService, OrchestratorService],
+    imports: [HttpClientTestingModule, NgbModalModule]
   });
 
   it('should be created', () => {
 
 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.
         func();
       } else {
         this.modalService.show(OrchestratorDocModalComponent, {
-          initialState: {
-            actionDescription: actionDescription,
-            itemDescription: itemDescription
-          }
+          actionDescription: actionDescription,
+          itemDescription: itemDescription
         });
       }
     });
 
--- /dev/null
+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();
+  }));
+});
 
--- /dev/null
+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();
+  }
+}
 
 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';
 }
 
 /**
- * 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 {