From c735ff86e0a5e26327907cca3898f2265ca904d8 Mon Sep 17 00:00:00 2001 From: Tiago Melo Date: Fri, 29 May 2020 14:33:19 +0000 Subject: [PATCH] mgr/dashboard: Use ng-bootstrap for Modal Fixes: https://tracker.ceph.com/issues/45759 Signed-off-by: Tiago Melo --- .../src/app/ceph/block/block.module.ts | 2 - ...scsi-target-discovery-modal.component.html | 4 +- ...i-target-discovery-modal.component.spec.ts | 4 +- .../iscsi-target-discovery-modal.component.ts | 6 +- .../iscsi-target-form.component.ts | 13 +- ...target-image-settings-modal.component.html | 4 +- ...get-image-settings-modal.component.spec.ts | 4 +- ...i-target-image-settings-modal.component.ts | 6 +- ...i-target-iqn-settings-modal.component.html | 4 +- ...arget-iqn-settings-modal.component.spec.ts | 4 +- ...csi-target-iqn-settings-modal.component.ts | 6 +- .../iscsi-target-list.component.ts | 29 ++-- .../bootstrap-create-modal.component.html | 4 +- .../bootstrap-create-modal.component.spec.ts | 6 +- .../bootstrap-create-modal.component.ts | 4 +- .../bootstrap-import-modal.component.html | 4 +- .../bootstrap-import-modal.component.spec.ts | 6 +- .../bootstrap-import-modal.component.ts | 6 +- .../edit-site-name-modal.component.html | 4 +- .../edit-site-name-modal.component.spec.ts | 8 +- .../edit-site-name-modal.component.ts | 6 +- .../ceph/block/mirroring/mirroring.module.ts | 2 - .../mirroring/overview/overview.component.ts | 13 +- .../pool-edit-mode-modal.component.html | 4 +- .../pool-edit-mode-modal.component.spec.ts | 8 +- .../pool-edit-mode-modal.component.ts | 6 +- .../pool-edit-peer-modal.component.html | 4 +- .../pool-edit-peer-modal.component.spec.ts | 12 +- .../pool-edit-peer-modal.component.ts | 6 +- .../pool-list/pool-list.component.ts | 51 +++--- .../block/rbd-list/rbd-list.component.spec.ts | 2 - .../ceph/block/rbd-list/rbd-list.component.ts | 43 +++-- .../rbd-namespace-form-modal.component.html | 4 +- ...rbd-namespace-form-modal.component.spec.ts | 4 +- .../rbd-namespace-form-modal.component.ts | 6 +- .../rbd-namespace-list.component.ts | 49 +++--- .../rbd-snapshot-form-modal.component.html | 4 +- .../rbd-snapshot-form-modal.component.spec.ts | 4 +- .../rbd-snapshot-form-modal.component.ts | 8 +- .../rbd-snapshot-list.component.spec.ts | 81 ++++++---- .../rbd-snapshot-list.component.ts | 33 ++-- .../rbd-trash-list.component.ts | 33 ++-- .../rbd-trash-move-modal.component.html | 4 +- .../rbd-trash-move-modal.component.spec.ts | 8 +- .../rbd-trash-move-modal.component.ts | 6 +- .../rbd-trash-purge-modal.component.html | 4 +- .../rbd-trash-purge-modal.component.spec.ts | 14 +- .../rbd-trash-purge-modal.component.ts | 6 +- .../rbd-trash-restore-modal.component.html | 4 +- .../rbd-trash-restore-modal.component.spec.ts | 14 +- .../rbd-trash-restore-modal.component.ts | 6 +- .../cephfs-clients.component.ts | 21 ++- .../cephfs-directories.component.spec.ts | 68 ++++---- .../cephfs-directories.component.ts | 125 +++++++------- .../src/app/ceph/cluster/cluster.module.ts | 2 - .../app/ceph/cluster/hosts/hosts.component.ts | 25 ++- .../inventory-devices.component.ts | 62 ++++--- .../osd-creation-preview-modal.component.html | 4 +- ...d-creation-preview-modal.component.spec.ts | 4 +- .../osd-creation-preview-modal.component.ts | 6 +- .../osd-devices-selection-groups.component.ts | 23 ++- ...osd-devices-selection-modal.component.html | 4 +- ...-devices-selection-modal.component.spec.ts | 4 +- .../osd-devices-selection-modal.component.ts | 6 +- .../osd-flags-modal.component.html | 4 +- .../osd-flags-modal.component.spec.ts | 15 +- .../osd-flags-modal.component.ts | 8 +- .../osd/osd-form/osd-form.component.ts | 10 +- .../osd/osd-list/osd-list.component.spec.ts | 8 +- .../osd/osd-list/osd-list.component.ts | 153 +++++++++--------- .../osd-pg-scrub-modal.component.html | 4 +- .../osd-pg-scrub-modal.component.spec.ts | 5 +- .../osd-pg-scrub-modal.component.ts | 8 +- .../osd-recv-speed-modal.component.html | 4 +- .../osd-recv-speed-modal.component.spec.ts | 5 +- .../osd-recv-speed-modal.component.ts | 8 +- .../osd-reweight-modal.component.html | 4 +- .../osd-reweight-modal.component.spec.ts | 4 +- .../osd-reweight-modal.component.ts | 6 +- .../osd-scrub-modal.component.html | 4 +- .../osd-scrub-modal.component.spec.ts | 4 +- .../osd-scrub-modal.component.ts | 8 +- .../silence-form.component.spec.ts | 6 +- .../silence-form/silence-form.component.ts | 16 +- .../silence-list.component.spec.ts | 11 +- .../silence-list/silence-list.component.ts | 59 ++++--- .../silence-matcher-modal.component.html | 4 +- .../silence-matcher-modal.component.spec.ts | 5 +- .../silence-matcher-modal.component.ts | 6 +- .../ceph/nfs/nfs-list/nfs-list.component.ts | 29 ++-- .../crush-rule-form-modal.component.html | 4 +- .../crush-rule-form-modal.component.spec.ts | 4 +- .../crush-rule-form-modal.component.ts | 6 +- ...ure-code-profile-form-modal.component.html | 4 +- ...-code-profile-form-modal.component.spec.ts | 4 +- ...asure-code-profile-form-modal.component.ts | 6 +- .../pool-form/pool-form.component.spec.ts | 79 +++++---- .../pool/pool-form/pool-form.component.ts | 29 ++-- .../pool-list/pool-list.component.spec.ts | 8 +- .../pool/pool-list/pool-list.component.ts | 23 ++- .../rgw-bucket-list.component.spec.ts | 2 - .../rgw-bucket-list.component.ts | 60 ++++--- .../rgw-user-capability-modal.component.html | 4 +- ...gw-user-capability-modal.component.spec.ts | 4 +- .../rgw-user-capability-modal.component.ts | 6 +- .../rgw-user-details.component.spec.ts | 3 +- .../rgw-user-details.component.ts | 12 +- .../rgw-user-form.component.spec.ts | 3 +- .../rgw-user-form/rgw-user-form.component.ts | 46 +++--- .../rgw-user-list.component.spec.ts | 10 +- .../rgw-user-list/rgw-user-list.component.ts | 56 ++++--- .../rgw-user-s3-key-modal.component.html | 4 +- .../rgw-user-s3-key-modal.component.spec.ts | 4 +- .../rgw-user-s3-key-modal.component.ts | 6 +- .../rgw-user-subuser-modal.component.html | 2 +- .../rgw-user-subuser-modal.component.spec.ts | 4 +- .../rgw-user-subuser-modal.component.ts | 6 +- .../rgw-user-swift-key-modal.component.html | 4 +- ...rgw-user-swift-key-modal.component.spec.ts | 4 +- .../rgw-user-swift-key-modal.component.ts | 4 +- .../frontend/src/app/ceph/rgw/rgw.module.ts | 2 - .../core/auth/login/login.component.spec.ts | 4 +- .../app/core/auth/login/login.component.ts | 10 +- .../auth/role-form/role-form.component.ts | 3 - .../auth/role-list/role-list.component.ts | 63 ++++---- .../user-form/user-form.component.spec.ts | 10 +- .../auth/user-form/user-form.component.ts | 11 +- .../auth/user-list/user-list.component.ts | 20 +-- .../navigation/about/about.component.html | 2 +- .../navigation/about/about.component.spec.ts | 4 +- .../core/navigation/about/about.component.ts | 4 +- .../dashboard-help.component.ts | 10 +- .../shared/components/components.module.ts | 2 - .../confirmation-modal.component.spec.ts | 89 +++------- .../confirmation-modal.component.ts | 17 +- ...critical-confirmation-modal.component.html | 4 +- ...tical-confirmation-modal.component.spec.ts | 85 ++++------ .../critical-confirmation-modal.component.ts | 6 +- .../form-modal/form-modal.component.html | 4 +- .../form-modal/form-modal.component.spec.ts | 5 +- .../form-modal/form-modal.component.ts | 6 +- .../components/modal/modal.component.scss | 4 + .../components/modal/modal.component.spec.ts | 9 +- .../components/modal/modal.component.ts | 8 +- .../orchestrator-doc-modal.component.html | 4 +- .../orchestrator-doc-modal.component.spec.ts | 4 +- .../orchestrator-doc-modal.component.ts | 6 +- .../services/dep-checker.service.spec.ts | 6 +- .../shared/services/dep-checker.service.ts | 11 +- .../app/shared/services/modal.service.spec.ts | 59 +++++++ .../src/app/shared/services/modal.service.ts | 28 ++++ .../frontend/src/testing/unit-test-helper.ts | 20 +-- 152 files changed, 1117 insertions(+), 1143 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/services/modal.service.ts diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts index 702af5d37cf02..1a3800c90f69e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/block.module.ts @@ -7,7 +7,6 @@ import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; import { TreeModule } from 'angular-tree-component'; import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation'; import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; -import { ModalModule } from 'ngx-bootstrap/modal'; import { ActionLabels, URLVerbs } from '../../shared/constants/app.constants'; import { FeatureTogglesGuardService } from '../../shared/services/feature-toggles-guard.service'; @@ -48,7 +47,6 @@ import { RbdTrashRestoreModalComponent } from './rbd-trash-restore-modal/rbd-tra NgbNavModule, BsDatepickerModule.forRoot(), NgbTooltipModule, - ModalModule.forRoot(), SharedModule, RouterModule, NgBootstrapFormValidationModule, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html index 605f1682928e2..ff05fa160868b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.html @@ -1,4 +1,4 @@ - + Discovery Authentication @@ -126,7 +126,7 @@ [form]="discoveryForm" *ngIf="hasPermission" i18n>Submit - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts index 6d867cad0e096..ed0a6652187cc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.spec.ts @@ -8,7 +8,7 @@ import { ReactiveFormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; import { @@ -39,7 +39,7 @@ describe('IscsiTargetDiscoveryModalComponent', () => { ToastrModule.forRoot(), RouterTestingModule ], - providers: [i18nProviders, BsModalRef] + providers: [i18nProviders, NgbActiveModal] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts index fcf9e27c142cb..9f150747d7560 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-discovery-modal/iscsi-target-discovery-modal.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core'; import { FormControl, Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { IscsiService } from '../../../shared/api/iscsi.service'; import { NotificationType } from '../../../shared/enum/notification-type.enum'; @@ -27,7 +27,7 @@ export class IscsiTargetDiscoveryModalComponent implements OnInit { constructor( private authStorageService: AuthStorageService, - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private iscsiService: IscsiService, private notificationService: NotificationService, private i18n: I18n @@ -113,7 +113,7 @@ export class IscsiTargetDiscoveryModalComponent implements OnInit { NotificationType.success, this.i18n('Updated discovery authentication') ); - this.bsModalRef.hide(); + this.activeModal.close(); }, () => { this.discoveryForm.setErrors({ cdSubmitButton: true }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts index 68d24a4613abe..c5bead7dc3886 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts @@ -2,9 +2,9 @@ import { Component, OnInit } from '@angular/core'; import { FormArray, FormControl, Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { forkJoin } from 'rxjs'; import { IscsiService } from '../../../shared/api/iscsi.service'; @@ -17,6 +17,7 @@ import { CdForm } from '../../../shared/forms/cd-form'; import { CdFormGroup } from '../../../shared/forms/cd-form-group'; import { CdValidators } from '../../../shared/forms/cd-validators'; import { FinishedTask } from '../../../shared/models/finished-task'; +import { ModalService } from '../../../shared/services/modal.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; import { IscsiTargetImageSettingsModalComponent } from '../iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component'; import { IscsiTargetIqnSettingsModalComponent } from '../iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component'; @@ -29,7 +30,7 @@ import { IscsiTargetIqnSettingsModalComponent } from '../iscsi-target-iqn-settin export class IscsiTargetFormComponent extends CdForm implements OnInit { cephIscsiConfigVersion: number; targetForm: CdFormGroup; - modalRef: BsModalRef; + modalRef: NgbModalRef; api_version = 0; minimum_gateways = 1; target_default_controls: any; @@ -90,7 +91,7 @@ export class IscsiTargetFormComponent extends CdForm implements OnInit { constructor( private iscsiService: IscsiService, - private modalService: BsModalService, + private modalService: ModalService, private rbdService: RbdService, private router: Router, private route: ActivatedRoute, @@ -785,7 +786,7 @@ export class IscsiTargetFormComponent extends CdForm implements OnInit { target_controls_limits: this.target_controls_limits }; - this.modalRef = this.modalService.show(IscsiTargetIqnSettingsModalComponent, { initialState }); + this.modalRef = this.modalService.show(IscsiTargetIqnSettingsModalComponent, initialState); } imageSettingsModal(image: string) { @@ -799,9 +800,7 @@ export class IscsiTargetFormComponent extends CdForm implements OnInit { control: this.targetForm.get('disks') }; - this.modalRef = this.modalService.show(IscsiTargetImageSettingsModalComponent, { - initialState - }); + this.modalRef = this.modalService.show(IscsiTargetImageSettingsModalComponent, initialState); } validFeatures(image: Record, backstore: string) { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html index 8bd8d45975ed0..21d8d00e213a5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.html @@ -1,4 +1,4 @@ - + Configure  {{ image }} @@ -86,7 +86,7 @@ Confirm - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts index 921292bcdb046..10ac2c762bddb 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.spec.ts @@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; import { SharedModule } from '../../../shared/shared.module'; @@ -17,7 +17,7 @@ describe('IscsiTargetImageSettingsModalComponent', () => { configureTestBed({ declarations: [IscsiTargetImageSettingsModalComponent, IscsiSettingComponent], imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts index f238d3b4c698c..36d2e70f0d579 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-image-settings-modal/iscsi-target-image-settings-modal.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core'; import { AbstractControl, FormControl } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { IscsiService } from '../../../shared/api/iscsi.service'; import { CdFormGroup } from '../../../shared/forms/cd-form-group'; @@ -23,7 +23,7 @@ export class IscsiTargetImageSettingsModalComponent implements OnInit { settingsForm: CdFormGroup; - constructor(public modalRef: BsModalRef, public iscsiService: IscsiService) {} + constructor(public activeModal: NgbActiveModal, public iscsiService: IscsiService) {} ngOnInit() { const fg: Record = { @@ -77,6 +77,6 @@ export class IscsiTargetImageSettingsModalComponent implements OnInit { this.imagesSettings[this.image][backstore] = settings; this.imagesSettings = { ...this.imagesSettings }; this.control.updateValueAndValidity({ emitEvent: false }); - this.modalRef.hide(); + this.activeModal.close(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html index 7eeacef4f5583..2df24f42c637a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.html @@ -1,4 +1,4 @@ - + Advanced Settings @@ -26,7 +26,7 @@ Confirm - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts index 521bcbf22d807..ac6d883499eff 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.spec.ts @@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; import { SharedModule } from '../../../shared/shared.module'; @@ -17,7 +17,7 @@ describe('IscsiTargetIqnSettingsModalComponent', () => { configureTestBed({ declarations: [IscsiTargetIqnSettingsModalComponent, IscsiSettingComponent], imports: [SharedModule, ReactiveFormsModule, HttpClientTestingModule, RouterTestingModule], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts index 8e92f707ce07f..dcb7a754c409b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-iqn-settings-modal/iscsi-target-iqn-settings-modal.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { IscsiService } from '../../../shared/api/iscsi.service'; import { CdFormGroup } from '../../../shared/forms/cd-form-group'; @@ -19,7 +19,7 @@ export class IscsiTargetIqnSettingsModalComponent implements OnInit { settingsForm: CdFormGroup; - constructor(public modalRef: BsModalRef, public iscsiService: IscsiService) {} + constructor(public activeModal: NgbActiveModal, public iscsiService: IscsiService) {} ngOnInit() { const fg: Record = {}; @@ -39,7 +39,7 @@ export class IscsiTargetIqnSettingsModalComponent implements OnInit { }); this.target_controls.setValue(settings); - this.modalRef.hide(); + this.activeModal.close(); } getTargetControlLimits(setting: string) { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts index 00f830978f31f..91361703629df 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.ts @@ -1,8 +1,8 @@ import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { Subscription } from 'rxjs'; import { IscsiService } from '../../../shared/api/iscsi.service'; @@ -21,6 +21,7 @@ import { Task } from '../../../shared/models/task'; import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; import { NotAvailablePipe } from '../../../shared/pipes/not-available.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { SummaryService } from '../../../shared/services/summary.service'; import { TaskListService } from '../../../shared/services/task-list.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; @@ -39,7 +40,7 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, available: boolean = undefined; columns: CdTableColumn[]; docsUrl: string; - modalRef: BsModalRef; + modalRef: NgbModalRef; permission: Permission; selection = new CdTableSelection(); cephIscsiConfigVersion: number; @@ -66,7 +67,7 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, private cephReleaseNamePipe: CephReleaseNamePipe, private notAvailablePipe: NotAvailablePipe, private summaryservice: SummaryService, - private modalService: BsModalService, + private modalService: ModalService, private taskWrapper: TaskWrapperService, public actionLabels: ActionLabelsI18n ) { @@ -221,21 +222,19 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, const target_iqn = this.selection.first().target_iqn; this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: this.i18n('iSCSI target'), - itemNames: [target_iqn], - submitActionObservable: () => - this.taskWrapper.wrapTaskAroundCall({ - task: new FinishedTask('iscsi/target/delete', { - target_iqn: target_iqn - }), - call: this.iscsiService.deleteTarget(target_iqn) - }) - } + itemDescription: this.i18n('iSCSI target'), + itemNames: [target_iqn], + submitActionObservable: () => + this.taskWrapper.wrapTaskAroundCall({ + task: new FinishedTask('iscsi/target/delete', { + target_iqn: target_iqn + }), + call: this.iscsiService.deleteTarget(target_iqn) + }) }); } configureDiscoveryAuth() { - this.modalService.show(IscsiTargetDiscoveryModalComponent, {}); + this.modalService.show(IscsiTargetDiscoveryModalComponent); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html index 7c1c62b2d4da1..3e2a1867ae3c3 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-create-modal/bootstrap-create-modal.component.html @@ -1,4 +1,4 @@ - + Create Bootstrap Token @@ -82,7 +82,7 @@ diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts index 0cf0d67ebf41d..91573a80649d9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.spec.ts @@ -4,7 +4,7 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper'; @@ -53,7 +53,7 @@ describe('OsdDevicesSelectionModalComponent', () => { RouterTestingModule, ToastrModule.forRoot() ], - providers: [BsModalRef, i18nProviders], + providers: [NgbActiveModal, i18nProviders], declarations: [OsdDevicesSelectionModalComponent, InventoryDevicesComponent] }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts index 5fb84e0169228..deb613a3f0cce 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-devices-selection-modal/osd-devices-selection-modal.component.ts @@ -1,8 +1,8 @@ import { AfterViewInit, Component, EventEmitter, Output, ViewChild } from '@angular/core'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { TableColumnProp } from '@swimlane/ngx-datatable'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ActionLabelsI18n } from '../../../../shared/constants/app.constants'; import { Icons } from '../../../../shared/enum/icons.enum'; @@ -41,7 +41,7 @@ export class OsdDevicesSelectionModalComponent implements AfterViewInit { constructor( private formBuilder: CdFormBuilder, - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, public actionLabels: ActionLabelsI18n ) { this.action = actionLabels.ADD; @@ -82,6 +82,6 @@ export class OsdDevicesSelectionModalComponent implements AfterViewInit { onSubmit() { this.submitAction.emit(this.event); - this.bsModalRef.hide(); + this.activeModal.close(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html index fa4245327988d..f3094d44501f0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.html @@ -1,4 +1,4 @@ - + Cluster-wide OSD Flags @@ -34,7 +34,7 @@ (submitAction)="submitAction()" [form]="osdFlagsForm" i18n>Submit - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts index 7470f48566d6c..b73a495af8e19 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.spec.ts @@ -3,8 +3,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; -import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper'; @@ -28,14 +28,13 @@ describe('OsdFlagsModalComponent', () => { configureTestBed({ imports: [ ReactiveFormsModule, - ModalModule.forRoot(), SharedModule, HttpClientTestingModule, RouterTestingModule, ToastrModule.forRoot() ], declarations: [OsdFlagsModalComponent], - providers: [BsModalRef, i18nProviders] + providers: [i18nProviders, NgbActiveModal] }); beforeEach(() => { @@ -63,7 +62,7 @@ describe('OsdFlagsModalComponent', () => { describe('test submitAction', function () { let notificationType: NotificationType; let notificationService: NotificationService; - let bsModalRef: BsModalRef; + let bsModalRef: NgbActiveModal; beforeEach(() => { notificationService = TestBed.inject(NotificationService); @@ -71,8 +70,8 @@ describe('OsdFlagsModalComponent', () => { notificationType = type; }); - bsModalRef = TestBed.inject(BsModalRef); - spyOn(bsModalRef, 'hide').and.callThrough(); + bsModalRef = TestBed.inject(NgbActiveModal); + spyOn(bsModalRef, 'close').and.callThrough(); component.unknownFlags = ['foo']; }); @@ -84,7 +83,7 @@ describe('OsdFlagsModalComponent', () => { expect(req.request.body).toEqual({ flags: ['pause', 'purged_snapdirs', 'foo'] }); expect(notificationType).toBe(NotificationType.success); - expect(component.bsModalRef.hide).toHaveBeenCalledTimes(1); + expect(component.activeModal.close).toHaveBeenCalledTimes(1); }); it('should hide modal if request fails', () => { @@ -94,7 +93,7 @@ describe('OsdFlagsModalComponent', () => { req.flush([], { status: 500, statusText: 'failure' }); expect(notificationService.show).toHaveBeenCalledTimes(0); - expect(component.bsModalRef.hide).toHaveBeenCalledTimes(1); + expect(component.activeModal.close).toHaveBeenCalledTimes(1); }); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts index 12520e41b4e68..e2cc01a764d03 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-flags-modal/osd-flags-modal.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { OsdService } from '../../../../shared/api/osd.service'; import { NotificationType } from '../../../../shared/enum/notification-type.enum'; @@ -121,7 +121,7 @@ export class OsdFlagsModalComponent implements OnInit { unknownFlags: string[] = []; constructor( - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private authStorageService: AuthStorageService, private osdService: OsdService, private notificationService: NotificationService, @@ -152,10 +152,10 @@ export class OsdFlagsModalComponent implements OnInit { this.osdService.updateFlags(newFlags).subscribe( () => { this.notificationService.show(NotificationType.success, this.i18n('Updated OSD Flags')); - this.bsModalRef.hide(); + this.activeModal.close(); }, () => { - this.bsModalRef.hide(); + this.activeModal.close(); } ); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts index a6ad22f05cb5a..735680c0b9a02 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts @@ -4,7 +4,6 @@ import { Router } from '@angular/router'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { OrchestratorService } from '../../../../shared/api/orchestrator.service'; import { SubmitButtonComponent } from '../../../../shared/components/submit-button/submit-button.component'; @@ -14,6 +13,7 @@ import { CdForm } from '../../../../shared/forms/cd-form'; import { CdFormGroup } from '../../../../shared/forms/cd-form-group'; import { CdTableColumn } from '../../../../shared/models/cd-table-column'; import { AuthStorageService } from '../../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../../shared/services/modal.service'; import { InventoryDevice } from '../../inventory/inventory-devices/inventory-device.model'; import { OsdCreationPreviewModalComponent } from '../osd-creation-preview-modal/osd-creation-preview-modal.component'; import { DevicesSelectionChangeEvent } from '../osd-devices-selection-groups/devices-selection-change-event.interface'; @@ -69,7 +69,7 @@ export class OsdFormComponent extends CdForm implements OnInit { private i18n: I18n, private orchService: OrchestratorService, private router: Router, - private bsModalService: BsModalService + private modalService: ModalService ) { super(); this.resource = this.i18n('OSDs'); @@ -208,10 +208,10 @@ export class OsdFormComponent extends CdForm implements OnInit { // use user name and timestamp for drive group name const user = this.authStorageService.getUsername(); this.driveGroup.setName(`dashboard-${user}-${_.now()}`); - const modalRef = this.bsModalService.show(OsdCreationPreviewModalComponent, { - initialState: { driveGroups: [this.driveGroup.spec] } + const modalRef = this.modalService.show(OsdCreationPreviewModalComponent, { + driveGroups: [this.driveGroup.spec] }); - modalRef.content.submitAction.subscribe(() => { + modalRef.componentInstance.submitAction.subscribe(() => { this.router.navigate(['/osd']); }); this.previewButton.loading = false; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts index ea0db7a3a608a..44792948d6957 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.spec.ts @@ -7,7 +7,6 @@ import { RouterTestingModule } from '@angular/router/testing'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { EMPTY, of } from 'rxjs'; @@ -27,6 +26,7 @@ import { CdTableAction } from '../../../../shared/models/cd-table-action'; import { CdTableSelection } from '../../../../shared/models/cd-table-selection'; import { Permissions } from '../../../../shared/models/permissions'; import { AuthStorageService } from '../../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../../shared/services/modal.service'; import { CephModule } from '../../../ceph.module'; import { PerformanceCounterModule } from '../../../performance-counter/performance-counter.module'; import { OsdReweightModalComponent } from '../osd-reweight-modal/osd-reweight-modal.component'; @@ -107,7 +107,7 @@ describe('OsdListComponent', () => { providers: [ { provide: AuthStorageService, useValue: fakeAuthStorageService }, TableActionsComponent, - BsModalService, + ModalService, i18nProviders ] }); @@ -116,7 +116,7 @@ describe('OsdListComponent', () => { fixture = TestBed.createComponent(OsdListComponent); component = fixture.componentInstance; osdService = TestBed.inject(OsdService); - modalServiceShowSpy = spyOn(TestBed.inject(BsModalService), 'show').and.stub(); + modalServiceShowSpy = spyOn(TestBed.inject(ModalService), 'show').and.stub(); }); it('should create', () => { @@ -430,7 +430,7 @@ describe('OsdListComponent', () => { ): void => { const osdServiceSpy = spyOn(osdService, osdServiceMethodName).and.callFake(() => EMPTY); openActionModal(actionName); - const initialState = modalServiceShowSpy.calls.first().args[1].initialState; + const initialState = modalServiceShowSpy.calls.first().args[1]; const submit = initialState.onSubmit || initialState.submitAction; submit.call(component); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts index ed0f1cdd7e045..67224ce68718b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.ts @@ -2,9 +2,9 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { FormControl } from '@angular/forms'; import { Router } from '@angular/router'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { forkJoin as observableForkJoin, Observable } from 'rxjs'; import { OsdService } from '../../../../shared/api/osd.service'; @@ -26,6 +26,7 @@ import { Permissions } from '../../../../shared/models/permissions'; import { DimlessBinaryPipe } from '../../../../shared/pipes/dimless-binary.pipe'; import { AuthStorageService } from '../../../../shared/services/auth-storage.service'; import { DepCheckerService } from '../../../../shared/services/dep-checker.service'; +import { ModalService } from '../../../../shared/services/modal.service'; import { NotificationService } from '../../../../shared/services/notification.service'; import { TaskWrapperService } from '../../../../shared/services/task-wrapper.service'; import { URLBuilderService } from '../../../../shared/services/url-builder.service'; @@ -61,7 +62,7 @@ export class OsdListComponent extends ListWithDetails implements OnInit { permissions: Permissions; tableActions: CdTableAction[]; - bsModalRef: BsModalRef; + bsModalRef: NgbModalRef; columns: CdTableColumn[]; clusterWideActions: CdTableAction[]; icons = Icons; @@ -85,7 +86,7 @@ export class OsdListComponent extends ListWithDetails implements OnInit { private authStorageService: AuthStorageService, private osdService: OsdService, private dimlessBinaryPipe: DimlessBinaryPipe, - private modalService: BsModalService, + private modalService: ModalService, private i18n: I18n, private urlBuilder: URLBuilderService, private router: Router, @@ -378,31 +379,29 @@ export class OsdListComponent extends ListWithDetails implements OnInit { const selectedOsd = _.filter(this.osds, ['id', this.selection.first().id]).pop(); this.modalService.show(FormModalComponent, { - initialState: { - titleText: this.i18n('Edit OSD: {{id}}', { - id: selectedOsd.id - }), - fields: [ - { - type: 'text', - name: 'deviceClass', - value: selectedOsd.tree.device_class, - label: this.i18n('Device class'), - required: true - } - ], - submitButtonText: this.i18n('Edit OSD'), - onSubmit: (values: any) => { - this.osdService.update(selectedOsd.id, values.deviceClass).subscribe(() => { - this.notificationService.show( - NotificationType.success, - this.i18n(`Updated OSD '{{id}}'`, { - id: selectedOsd.id - }) - ); - this.getOsdList(); - }); + titleText: this.i18n('Edit OSD: {{id}}', { + id: selectedOsd.id + }), + fields: [ + { + type: 'text', + name: 'deviceClass', + value: selectedOsd.tree.device_class, + label: this.i18n('Device class'), + required: true } + ], + submitButtonText: this.i18n('Edit OSD'), + onSubmit: (values: any) => { + this.osdService.update(selectedOsd.id, values.deviceClass).subscribe(() => { + this.notificationService.show( + NotificationType.success, + this.i18n(`Updated OSD '{{id}}'`, { + id: selectedOsd.id + }) + ); + this.getOsdList(); + }); } }); } @@ -417,38 +416,34 @@ export class OsdListComponent extends ListWithDetails implements OnInit { deep: deep }; - this.bsModalRef = this.modalService.show(OsdScrubModalComponent, { initialState }); + this.bsModalRef = this.modalService.show(OsdScrubModalComponent, initialState); } configureFlagsAction() { - this.bsModalRef = this.modalService.show(OsdFlagsModalComponent, {}); + this.bsModalRef = this.modalService.show(OsdFlagsModalComponent); } showConfirmationModal(markAction: string, onSubmit: (id: number) => Observable) { this.bsModalRef = this.modalService.show(ConfirmationModalComponent, { - initialState: { - titleText: this.i18n('Mark OSD {{markAction}}', { markAction: markAction }), - buttonText: this.i18n('Mark {{markAction}}', { markAction: markAction }), - bodyTpl: this.markOsdConfirmationTpl, - bodyContext: { - markActionDescription: markAction - }, - onSubmit: () => { - observableForkJoin( - this.getSelectedOsdIds().map((osd: any) => onSubmit.call(this.osdService, osd)) - ).subscribe(() => this.bsModalRef.hide()); - } + titleText: this.i18n('Mark OSD {{markAction}}', { markAction: markAction }), + buttonText: this.i18n('Mark {{markAction}}', { markAction: markAction }), + bodyTpl: this.markOsdConfirmationTpl, + bodyContext: { + markActionDescription: markAction + }, + onSubmit: () => { + observableForkJoin( + this.getSelectedOsdIds().map((osd: any) => onSubmit.call(this.osdService, osd)) + ).subscribe(() => this.bsModalRef.close()); } }); } reweight() { const selectedOsd = this.osds.filter((o) => o.id === this.selection.first().id).pop(); - this.modalService.show(OsdReweightModalComponent, { - initialState: { - currentWeight: selectedOsd.weight, - osdId: selectedOsd.id - } + this.bsModalRef = this.modalService.show(OsdReweightModalComponent, { + currentWeight: selectedOsd.weight, + osdId: selectedOsd.id }); } @@ -511,39 +506,37 @@ export class OsdListComponent extends ListWithDetails implements OnInit { ): void { check(this.getSelectedOsdIds()).subscribe((result) => { const modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - actionDescription: actionDescription, - itemDescription: itemDescription, - bodyTemplate: this.criticalConfirmationTpl, - bodyContext: { - safeToPerform: result[checkKey], - message: result.message, - actionDescription: templateItemDescription, - osdIds: this.getSelectedOsdIds() - }, - childFormGroup: childFormGroup, - childFormGroupTemplate: childFormGroupTemplate, - submitAction: () => { - const observable = observableForkJoin( - this.getSelectedOsdIds().map((osd: any) => action.call(this.osdService, osd)) + actionDescription: actionDescription, + itemDescription: itemDescription, + bodyTemplate: this.criticalConfirmationTpl, + bodyContext: { + safeToPerform: result[checkKey], + message: result.message, + actionDescription: templateItemDescription, + osdIds: this.getSelectedOsdIds() + }, + childFormGroup: childFormGroup, + childFormGroupTemplate: childFormGroupTemplate, + submitAction: () => { + const observable = observableForkJoin( + this.getSelectedOsdIds().map((osd: any) => action.call(this.osdService, osd)) + ); + if (taskWrapped) { + observable.subscribe({ + error: () => { + this.getOsdList(); + modalRef.close(); + }, + complete: () => modalRef.close() + }); + } else { + observable.subscribe( + () => { + this.getOsdList(); + modalRef.close(); + }, + () => modalRef.close() ); - if (taskWrapped) { - observable.subscribe({ - error: () => { - this.getOsdList(); - modalRef.hide(); - }, - complete: () => modalRef.hide() - }); - } else { - observable.subscribe( - () => { - this.getOsdList(); - modalRef.hide(); - }, - () => modalRef.hide() - ); - } } } }); @@ -551,10 +544,10 @@ export class OsdListComponent extends ListWithDetails implements OnInit { } configureQosParamsAction() { - this.bsModalRef = this.modalService.show(OsdRecvSpeedModalComponent, {}); + this.bsModalRef = this.modalService.show(OsdRecvSpeedModalComponent); } configurePgScrubAction() { - this.bsModalRef = this.modalService.show(OsdPgScrubModalComponent, { class: 'modal-lg' }); + this.bsModalRef = this.modalService.show(OsdPgScrubModalComponent, { size: 'lg' }); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html index a0216f72a23fc..4568650ae6b5b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.html @@ -1,4 +1,4 @@ - + {{ action | titlecase }} {{ resource | upperFirst }} @@ -37,7 +37,7 @@ (submitAction)="submitAction()" i18n="form action button|Example: Create Pool@@formActionButton" [form]="osdPgScrubForm">{{ action | titlecase }} {{ resource | upperFirst }} - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts index f5c7ddd237159..083398d1ce06f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.spec.ts @@ -4,7 +4,7 @@ import { ReactiveFormsModule } from '@angular/forms'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; import { of as observableOf } from 'rxjs'; @@ -23,14 +23,13 @@ describe('OsdPgScrubModalComponent', () => { configureTestBed({ imports: [ HttpClientTestingModule, - ModalModule.forRoot(), ReactiveFormsModule, RouterTestingModule, SharedModule, ToastrModule.forRoot() ], declarations: [OsdPgScrubModalComponent], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts index 410f53f7a071b..e2b4c1d445007 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component.ts @@ -1,7 +1,7 @@ import { Component, ViewChild } from '@angular/core'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { forkJoin as observableForkJoin } from 'rxjs'; import { ConfigOptionComponent } from '../../../../shared/components/config-option/config-option.component'; @@ -35,7 +35,7 @@ export class OsdPgScrubModalComponent { advancedEnabled = false; constructor( - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private authStorageService: AuthStorageService, private notificationService: NotificationService, private i18n: I18n, @@ -60,10 +60,10 @@ export class OsdPgScrubModalComponent { NotificationType.success, this.i18n('Updated PG scrub options') ); - this.bsModalRef.hide(); + this.activeModal.close(); }, () => { - this.bsModalRef.hide(); + this.activeModal.close(); } ); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html index 26fb412c686c6..0bc4fef593433 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.html @@ -1,4 +1,4 @@ - + OSD Recovery Priority @@ -85,7 +85,7 @@ (submitAction)="submitAction()" [form]="osdRecvSpeedForm" i18n>Submit - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts index d050b5932ca1c..5c08024a86b69 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts @@ -3,8 +3,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; -import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of as observableOf } from 'rxjs'; @@ -21,14 +21,13 @@ describe('OsdRecvSpeedModalComponent', () => { configureTestBed({ imports: [ HttpClientTestingModule, - ModalModule.forRoot(), ReactiveFormsModule, RouterTestingModule, SharedModule, ToastrModule.forRoot() ], declarations: [OsdRecvSpeedModalComponent], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); let configOptions: any[] = []; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts index eaaa70a4bc356..4eaffd27fbcdf 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { FormControl, Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ConfigurationService } from '../../../../shared/api/configuration.service'; import { OsdService } from '../../../../shared/api/osd.service'; @@ -27,7 +27,7 @@ export class OsdRecvSpeedModalComponent implements OnInit { priorityAttrs = {}; constructor( - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private authStorageService: AuthStorageService, private configService: ConfigurationService, private notificationService: NotificationService, @@ -228,10 +228,10 @@ export class OsdRecvSpeedModalComponent implements OnInit { value: this.osdRecvSpeedForm.getValue('priority') }) ); - this.bsModalRef.hide(); + this.activeModal.close(); }, () => { - this.bsModalRef.hide(); + this.activeModal.close(); } ); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html index 7760dd09680ca..9e67bbb6e1be2 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.html @@ -1,4 +1,4 @@ - + Reweight OSD: {{ osdId }} @@ -33,7 +33,7 @@ [form]="reweightForm" [disabled]="reweightForm.invalid" i18n>Reweight - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts index e59f360340adc..7b98b6d0340df 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.spec.ts @@ -3,7 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { of } from 'rxjs'; import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper'; @@ -26,7 +26,7 @@ describe('OsdReweightModalComponent', () => { SubmitButtonComponent, BackButtonComponent ], - providers: [OsdService, BsModalRef, CdFormBuilder, i18nProviders] + providers: [OsdService, NgbActiveModal, CdFormBuilder, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts index 4f884d1bdef4c..fad56e284c5b9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-reweight-modal/osd-reweight-modal.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { Validators } from '@angular/forms'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { OsdService } from '../../../../shared/api/osd.service'; import { CdFormBuilder } from '../../../../shared/forms/cd-form-builder'; @@ -18,7 +18,7 @@ export class OsdReweightModalComponent implements OnInit { reweightForm: CdFormGroup; constructor( - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private osdService: OsdService, private fb: CdFormBuilder ) {} @@ -40,6 +40,6 @@ export class OsdReweightModalComponent implements OnInit { reweight() { this.osdService .reweight(this.osdId, this.reweightForm.value.weight) - .subscribe(() => this.bsModalRef.hide()); + .subscribe(() => this.activeModal.close()); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html index f5a5bb2f1ced3..c82063b3c09c4 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.html @@ -1,4 +1,4 @@ - + OSDs {deep, select, 1 {Deep }}Scrub @@ -16,7 +16,7 @@ Submit - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts index a32e173678c91..a20df3bb3a244 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.spec.ts @@ -2,7 +2,7 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, i18nProviders } from '../../../../../testing/unit-test-helper'; import { OsdService } from '../../../../shared/api/osd.service'; @@ -31,7 +31,7 @@ describe('OsdScrubModalComponent', () => { declarations: [OsdScrubModalComponent, JoinPipe], schemas: [NO_ERRORS_SCHEMA], providers: [ - BsModalRef, + NgbActiveModal, JoinPipe, { provide: OsdService, useValue: fakeService }, { provide: NotificationService, useValue: fakeService }, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts index c19e523744527..c23fb50053746 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-scrub-modal/osd-scrub-modal.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit } from '@angular/core'; import { FormGroup } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { forkJoin } from 'rxjs'; import { OsdService } from '../../../../shared/api/osd.service'; @@ -21,7 +21,7 @@ export class OsdScrubModalComponent implements OnInit { selected: any[] = []; constructor( - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private osdService: OsdService, private notificationService: NotificationService, private i18n: I18n, @@ -45,9 +45,9 @@ export class OsdScrubModalComponent implements OnInit { }) ); - this.bsModalRef.hide(); + this.activeModal.close(); }, - () => this.bsModalRef.hide() + () => this.activeModal.close() ); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts index b331140d655dc..0c5b6b05902b4 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.spec.ts @@ -8,7 +8,6 @@ import { RouterTestingModule } from '@angular/router/testing'; import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; import { BsDatepickerDirective, BsDatepickerModule } from 'ngx-bootstrap/datepicker'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of, throwError } from 'rxjs'; @@ -26,6 +25,7 @@ import { CdFormGroup } from '../../../../shared/forms/cd-form-group'; import { AlertmanagerSilence } from '../../../../shared/models/alertmanager-silence'; import { Permission } from '../../../../shared/models/permissions'; import { AuthStorageService } from '../../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../../shared/services/modal.service'; import { NotificationService } from '../../../../shared/services/notification.service'; import { SharedModule } from '../../../../shared/shared.module'; import { SilenceFormComponent } from './silence-form.component'; @@ -460,10 +460,10 @@ describe('SilenceFormComponent', () => { addMatcher('alertname', 'alert.*', true); expectMatch(null); - const modalService = TestBed.inject(BsModalService); + const modalService = TestBed.inject(ModalService); spyOn(modalService, 'show').and.callFake(() => { return { - content: { + componentInstance: { preFillControls: (matcher: any) => { expect(matcher).toBe(component.matchers[0]); }, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts index 4f36ef92ad8f5..0449a8e048dea 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-form/silence-form.component.ts @@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { PrometheusService } from '../../../../shared/api/prometheus.service'; import { @@ -24,6 +23,7 @@ import { import { Permission } from '../../../../shared/models/permissions'; import { AlertmanagerAlert, PrometheusRule } from '../../../../shared/models/prometheus-alerts'; import { AuthStorageService } from '../../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../../shared/services/modal.service'; import { NotificationService } from '../../../../shared/services/notification.service'; import { PrometheusSilenceMatcherService } from '../../../../shared/services/prometheus-silence-matcher.service'; import { TimeDiffService } from '../../../../shared/services/time-diff.service'; @@ -79,7 +79,7 @@ export class SilenceFormComponent { private notificationService: NotificationService, private route: ActivatedRoute, private timeDiff: TimeDiffService, - private bsModalService: BsModalService, + private modalService: ModalService, private silenceMatcher: PrometheusSilenceMatcherService, private actionLabels: ActionLabelsI18n, private succeededLabels: SucceededActionLabelsI18n @@ -271,14 +271,14 @@ export class SilenceFormComponent { } showMatcherModal(index?: number) { - const modalRef = this.bsModalService.show(SilenceMatcherModalComponent); - const modal = modalRef.content as SilenceMatcherModalComponent; - modal.rules = this.rules; + const modalRef = this.modalService.show(SilenceMatcherModalComponent); + const modalComponent = modalRef.componentInstance as SilenceMatcherModalComponent; + modalComponent.rules = this.rules; if (_.isNumber(index)) { - modal.editMode = true; - modal.preFillControls(this.matchers[index]); + modalComponent.editMode = true; + modalComponent.preFillControls(this.matchers[index]); } - modalRef.content.submitAction.subscribe((matcher: AlertmanagerSilenceMatcher) => { + modalComponent.submitAction.subscribe((matcher: AlertmanagerSilenceMatcher) => { this.setMatcher(matcher, index); }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts index 088202764fe08..859b94b5d3e63 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.spec.ts @@ -3,7 +3,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of } from 'rxjs'; @@ -16,6 +15,7 @@ import { PrometheusService } from '../../../../shared/api/prometheus.service'; import { CriticalConfirmationModalComponent } from '../../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component'; import { TableActionsComponent } from '../../../../shared/datatable/table-actions/table-actions.component'; import { NotificationType } from '../../../../shared/enum/notification-type.enum'; +import { ModalService } from '../../../../shared/services/modal.service'; import { NotificationService } from '../../../../shared/services/notification.service'; import { SharedModule } from '../../../../shared/shared.module'; import { SilenceListComponent } from './silence-list.component'; @@ -29,7 +29,6 @@ describe('SilenceListComponent', () => { imports: [ BrowserAnimationsModule, SharedModule, - ModalModule.forRoot(), ToastrModule.forRoot(), RouterTestingModule, HttpClientTestingModule @@ -97,8 +96,8 @@ describe('SilenceListComponent', () => { const expireSilence = () => { component.expireSilence(); - const deletion: CriticalConfirmationModalComponent = component.modalRef.content; - deletion.modalRef = new BsModalRef(); + const deletion: CriticalConfirmationModalComponent = component.modalRef.componentInstance; + // deletion.modalRef = new BsModalRef(); deletion.ngOnInit(); deletion.callSubmitAction(); }; @@ -113,9 +112,9 @@ describe('SilenceListComponent', () => { const mockObservable = () => of([]); spyOn(component, 'refresh').and.callFake(mockObservable); spyOn(prometheusService, 'expireSilence').and.callFake(mockObservable); - spyOn(TestBed.inject(BsModalService), 'show').and.callFake((deletionClass, config) => { + spyOn(TestBed.inject(ModalService), 'show').and.callFake((deletionClass, config) => { return { - content: Object.assign(new deletionClass(), config.initialState) + componentInstance: Object.assign(new deletionClass(), config) }; }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts index d2b36f6af7549..64bb72b8df0e2 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-list/silence-list.component.ts @@ -1,8 +1,8 @@ import { Component } from '@angular/core'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import { SortDirection, SortPropDir } from '@swimlane/ngx-datatable'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { Observable, Subscriber } from 'rxjs'; import { PrometheusService } from '../../../../shared/api/prometheus.service'; @@ -22,6 +22,7 @@ import { CdTableSelection } from '../../../../shared/models/cd-table-selection'; import { Permission } from '../../../../shared/models/permissions'; import { CdDatePipe } from '../../../../shared/pipes/cd-date.pipe'; import { AuthStorageService } from '../../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../../shared/services/modal.service'; import { NotificationService } from '../../../../shared/services/notification.service'; import { URLBuilderService } from '../../../../shared/services/url-builder.service'; @@ -39,7 +40,7 @@ export class SilenceListComponent extends ListWithDetails { tableActions: CdTableAction[]; permission: Permission; selection = new CdTableSelection(); - modalRef: BsModalRef; + modalRef: NgbModalRef; customCss = { 'badge badge-danger': 'active', 'badge badge-warning': 'pending', @@ -52,7 +53,7 @@ export class SilenceListComponent extends ListWithDetails { private i18n: I18n, private cdDatePipe: CdDatePipe, private prometheusService: PrometheusService, - private modalService: BsModalService, + private modalService: ModalService, private notificationService: NotificationService, private urlBuilder: URLBuilderService, private actionLabels: ActionLabelsI18n, @@ -168,33 +169,31 @@ export class SilenceListComponent extends ListWithDetails { const i18nSilence = this.i18n('Silence'); const applicationName = 'Prometheus'; this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: i18nSilence, - itemNames: [id], - actionDescription: this.actionLabels.EXPIRE, - submitActionObservable: () => - new Observable((observer: Subscriber) => { - 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) => { + 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(); + } + ); + }) }); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html index 9285f3ff2b1d3..853b24520d20d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.html @@ -1,4 +1,4 @@ - + Matcher @@ -77,7 +77,7 @@ [form]="form"> {editMode, select, 1 {Update} other {Add}} - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts index 112626ff6e928..dc8117809635b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.spec.ts @@ -3,8 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, @@ -33,7 +32,7 @@ describe('SilenceMatcherModalComponent', () => { RouterTestingModule, ReactiveFormsModule ], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts index 9621b4acaa67c..cef04ef55595e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/prometheus/silence-matcher-modal/silence-matcher-modal.component.ts @@ -1,8 +1,8 @@ import { Component, EventEmitter, Output } from '@angular/core'; import { FormControl, Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { Observable } from 'rxjs'; import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators'; @@ -34,7 +34,7 @@ export class SilenceMatcherModalComponent { constructor( private formBuilder: CdFormBuilder, private silenceMatcher: PrometheusSilenceMatcherService, - public bsModalRef: BsModalRef + public activeModal: NgbActiveModal ) { this.createForm(); this.subscribeToChanges(); @@ -76,7 +76,7 @@ export class SilenceMatcherModalComponent { onSubmit() { this.submitAction.emit(this.form.value); - this.bsModalRef.hide(); + this.activeModal.close(); } search = (text$: Observable) => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts index 616c8ef7a347a..cf3994f0cac08 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/nfs/nfs-list/nfs-list.component.ts @@ -1,8 +1,8 @@ import { Component, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { Subscription } from 'rxjs'; import { NfsService } from '../../../shared/api/nfs.service'; @@ -20,6 +20,7 @@ import { FinishedTask } from '../../../shared/models/finished-task'; import { Permission } from '../../../shared/models/permissions'; import { Task } from '../../../shared/models/task'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { TaskListService } from '../../../shared/services/task-list.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; @@ -47,7 +48,7 @@ export class NfsListComponent extends ListWithDetails implements OnInit, OnDestr tableActions: CdTableAction[]; isDefaultCluster = false; - modalRef: BsModalRef; + modalRef: NgbModalRef; builders = { 'nfs/create': (metadata: any) => { @@ -62,7 +63,7 @@ export class NfsListComponent extends ListWithDetails implements OnInit, OnDestr constructor( private authStorageService: AuthStorageService, private i18n: I18n, - private modalService: BsModalService, + private modalService: ModalService, private nfsService: NfsService, private taskListService: TaskListService, private taskWrapper: TaskWrapperService, @@ -208,18 +209,16 @@ export class NfsListComponent extends ListWithDetails implements OnInit, OnDestr const export_id = this.selection.first().export_id; this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: this.i18n('NFS export'), - itemNames: [`${cluster_id}:${export_id}`], - submitActionObservable: () => - this.taskWrapper.wrapTaskAroundCall({ - task: new FinishedTask('nfs/delete', { - cluster_id: cluster_id, - export_id: export_id - }), - call: this.nfsService.delete(cluster_id, export_id) - }) - } + itemDescription: this.i18n('NFS export'), + itemNames: [`${cluster_id}:${export_id}`], + submitActionObservable: () => + this.taskWrapper.wrapTaskAroundCall({ + task: new FinishedTask('nfs/delete', { + cluster_id: cluster_id, + export_id: export_id + }), + call: this.nfsService.delete(cluster_id, export_id) + }) }); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html index 073b6e40f0af9..546a5ec437ab9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html @@ -1,4 +1,4 @@ - + {{ action | titlecase }} {{ resource | upperFirst }} @@ -117,7 +117,7 @@ {{ action | titlecase }} {{ resource | upperFirst }} - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts index 36696479d9bb6..62bdbebc367ba 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.spec.ts @@ -2,8 +2,8 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of } from 'rxjs'; @@ -79,7 +79,7 @@ describe('CrushRuleFormComponent', () => { PoolModule, NgBootstrapFormValidationModule.forRoot() ], - providers: [CrushRuleService, BsModalRef, i18nProviders] + providers: [CrushRuleService, NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts index 37324979bf9e6..dcf60e4cd88bc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.ts @@ -1,9 +1,9 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { CrushRuleService } from '../../../shared/api/crush-rule.service'; import { CrushNodeSelectionClass } from '../../../shared/classes/crush.node.selection.class'; @@ -33,7 +33,7 @@ export class CrushRuleFormModalComponent extends CrushNodeSelectionClass impleme constructor( private formBuilder: CdFormBuilder, - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private taskWrapper: TaskWrapperService, private crushRuleService: CrushRuleService, private i18n: I18n, @@ -102,7 +102,7 @@ export class CrushRuleFormModalComponent extends CrushNodeSelectionClass impleme this.form.setErrors({ cdSubmitButton: true }); }, complete: () => { - this.bsModalRef.hide(); + this.activeModal.close(); this.submitAction.emit(rule); } }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html index cbdeb36b1b4a4..1c98e1aaf91ed 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html @@ -1,4 +1,4 @@ - + {{ action | titlecase }} {{ resource | upperFirst }} @@ -338,7 +338,7 @@ {{ action | titlecase }} {{ resource | upperFirst }} - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts index 6ce5e83bf0996..7499a3148cd6c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts @@ -3,8 +3,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { RouterTestingModule } from '@angular/router/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of } from 'rxjs'; @@ -37,7 +37,7 @@ describe('ErasureCodeProfileFormModalComponent', () => { PoolModule, NgBootstrapFormValidationModule.forRoot() ], - providers: [ErasureCodeProfileService, BsModalRef, i18nProviders] + providers: [ErasureCodeProfileService, NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts index 298ceaff36d93..814b1696fe0c3 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts @@ -1,8 +1,8 @@ import { Component, EventEmitter, OnInit, Output } from '@angular/core'; import { Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ErasureCodeProfileService } from '../../../shared/api/erasure-code-profile.service'; import { CrushNodeSelectionClass } from '../../../shared/classes/crush.node.selection.class'; @@ -45,7 +45,7 @@ export class ErasureCodeProfileFormModalComponent extends CrushNodeSelectionClas constructor( private formBuilder: CdFormBuilder, - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private taskWrapper: TaskWrapperService, private ecpService: ErasureCodeProfileService, private i18n: I18n, @@ -324,7 +324,7 @@ export class ErasureCodeProfileFormModalComponent extends CrushNodeSelectionClas this.form.setErrors({ cdSubmitButton: true }); }, complete: () => { - this.bsModalRef.hide(); + this.activeModal.close(); this.submitAction.emit(profile); } }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts index eab97750c6c4f..af8999a807c10 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts @@ -6,10 +6,14 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ActivatedRoute, Router, Routes } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; -import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; +import { + NgbActiveModal, + NgbModalModule, + NgbModalRef, + NgbNavModule +} from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of } from 'rxjs'; @@ -32,6 +36,7 @@ import { ErasureCodeProfile } from '../../../shared/models/erasure-code-profile' import { Permission } from '../../../shared/models/permissions'; import { PoolFormInfo } from '../../../shared/models/pool-form-info'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; import { Pool } from '../pool'; import { PoolModule } from '../pool.module'; @@ -130,25 +135,29 @@ describe('PoolFormComponent', () => { const routes: Routes = [{ path: '404', component: NotFoundComponent }]; - configureTestBed({ - declarations: [NotFoundComponent], - imports: [ - BrowserAnimationsModule, - HttpClientTestingModule, - RouterTestingModule.withRoutes(routes), - ToastrModule.forRoot(), - NgbNavModule, - PoolModule, - NgBootstrapFormValidationModule.forRoot() - ], - providers: [ - ErasureCodeProfileService, - BsModalRef, - SelectBadgesComponent, - { provide: ActivatedRoute, useValue: { params: of({ name: 'somePoolName' }) } }, - i18nProviders - ] - }); + configureTestBed( + { + declarations: [NotFoundComponent], + imports: [ + BrowserAnimationsModule, + HttpClientTestingModule, + RouterTestingModule.withRoutes(routes), + ToastrModule.forRoot(), + NgbNavModule, + PoolModule, + NgBootstrapFormValidationModule.forRoot(), + NgbModalModule + ], + providers: [ + ErasureCodeProfileService, + NgbActiveModal, + SelectBadgesComponent, + { provide: ActivatedRoute, useValue: { params: of({ name: 'somePoolName' }) } }, + i18nProviders + ] + }, + [CriticalConfirmationModalComponent] + ); let navigationSpy: jasmine.Spy; @@ -782,9 +791,9 @@ describe('PoolFormComponent', () => { it('should select the newly created rule', () => { expect(form.getValue('crushRule').rule_name).toBe('rep1'); const name = 'awesomeRule'; - spyOn(TestBed.inject(BsModalService), 'show').and.callFake(() => { + spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => { return { - content: { + componentInstance: { submitAction: of({ name }) } }; @@ -845,11 +854,11 @@ describe('PoolFormComponent', () => { }; beforeEach(() => { - modalSpy = spyOn(TestBed.inject(BsModalService), 'show').and.callFake( - (deletionClass: any, config: any) => { - deletion = Object.assign(new deletionClass(), config.initialState); + modalSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake( + (deletionClass: any, initialState: any) => { + deletion = Object.assign(new deletionClass(), initialState); return { - content: deletion + componentInstance: deletion }; } ); @@ -906,7 +915,7 @@ describe('PoolFormComponent', () => { it('should hide the tooltip when clicking on add', () => { modalSpy.and.callFake((): any => ({ - content: { + componentInstance: { submitAction: of('someRule') } })); @@ -950,9 +959,9 @@ describe('PoolFormComponent', () => { spyOn(ecpService, 'list').and.callFake(() => of(infoReturn.erasure_code_profiles)); expect(form.getValue('erasureProfile').name).toBe('ecp1'); const name = 'awesomeProfile'; - spyOn(TestBed.inject(BsModalService), 'show').and.callFake(() => { + spyOn(TestBed.inject(ModalService), 'show').and.callFake(() => { return { - content: { + componentInstance: { submitAction: of({ name }) } }; @@ -969,11 +978,11 @@ describe('PoolFormComponent', () => { let deletion: CriticalConfirmationModalComponent; let deleteSpy: jasmine.Spy; let modalSpy: jasmine.Spy; - let modal: any; + let modal: NgbModalRef; const callEcpDeletion = () => { component.deleteErasureCodeProfile(); - modal.ref.content.callSubmitAction(); + modal.componentInstance.callSubmitAction(); }; const expectSuccessfulEcpDeletion = (name: string) => { @@ -994,10 +1003,10 @@ describe('PoolFormComponent', () => { beforeEach(() => { deletion = undefined; - modalSpy = spyOn(TestBed.inject(BsModalService), 'show').and.callFake( + modalSpy = spyOn(TestBed.inject(ModalService), 'show').and.callFake( (comp: any, init: any) => { modal = modalServiceShow(comp, init); - return modal.ref; + return modal; } ); deleteSpy = spyOn(ecpService, 'delete').and.callFake((name: string) => { @@ -1066,7 +1075,7 @@ describe('PoolFormComponent', () => { it('should hide the tooltip when clicking on add', () => { modalSpy.and.callFake((): any => ({ - content: { + componentInstance: { submitAction: of('someProfile') } })); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts index 1685f727b096e..f57b70a1231cb 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.ts @@ -5,7 +5,6 @@ import { ActivatedRoute, Router } from '@angular/router'; import { NgbNav, NgbTooltip } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { Observable, Subscription } from 'rxjs'; import { CrushRuleService } from '../../../shared/api/crush-rule.service'; @@ -32,6 +31,7 @@ import { PoolFormInfo } from '../../../shared/models/pool-form-info'; import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; import { FormatterService } from '../../../shared/services/formatter.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; import { CrushRuleFormModalComponent } from '../crush-rule-form-modal/crush-rule-form-modal.component'; import { ErasureCodeProfileFormModalComponent } from '../erasure-code-profile-form/erasure-code-profile-form-modal.component'; @@ -89,11 +89,10 @@ export class PoolFormComponent extends CdForm implements OnInit { private dimlessBinaryPipe: DimlessBinaryPipe, private route: ActivatedRoute, private router: Router, - private modalService: BsModalService, + private modalService: ModalService, private poolService: PoolService, private authStorageService: AuthStorageService, private formatter: FormatterService, - private bsModalService: BsModalService, private taskWrapper: TaskWrapperService, private ecpService: ErasureCodeProfileService, private crushRuleService: CrushRuleService, @@ -574,8 +573,8 @@ export class PoolFormComponent extends CdForm implements OnInit { private addModal(modalComponent: Type, reload: (name: string) => void) { this.hideOpenTooltips(); - const modalRef = this.bsModalService.show(modalComponent); - modalRef.content.submitAction.subscribe((item: any) => { + const modalRef = this.modalService.show(modalComponent); + modalRef.componentInstance.submitAction.subscribe((item: any) => { reload(item.name); }); } @@ -681,17 +680,15 @@ export class PoolFormComponent extends CdForm implements OnInit { } const name = value[nameAttribute]; this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription, - itemNames: [name], - submitActionObservable: () => { - const deletion = deleteFn(name); - deletion.subscribe(() => reloadFn()); - return this.taskWrapper.wrapTaskAroundCall({ - task: new FinishedTask(taskName, { name: name }), - call: deletion - }); - } + itemDescription, + itemNames: [name], + submitActionObservable: () => { + const deletion = deleteFn(name); + deletion.subscribe(() => reloadFn()); + return this.taskWrapper.wrapTaskAroundCall({ + task: new FinishedTask(taskName, { name: name }), + call: deletion + }); } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts index 3b1de559f3028..76a28e69c5e25 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.spec.ts @@ -5,7 +5,6 @@ import { RouterTestingModule } from '@angular/router/testing'; import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of } from 'rxjs'; @@ -19,6 +18,7 @@ import { PoolService } from '../../../shared/api/pool.service'; import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component'; import { ExecutingTask } from '../../../shared/models/executing-task'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { SummaryService } from '../../../shared/services/summary.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; import { SharedModule } from '../../../shared/shared.module'; @@ -151,7 +151,7 @@ describe('PoolListComponent', () => { const callDeletion = () => { component.deletePoolModal(); - const deletion: CriticalConfirmationModalComponent = component.modalRef.content; + const deletion: CriticalConfirmationModalComponent = component.modalRef.componentInstance; deletion.submitActionObservable(); }; @@ -171,9 +171,9 @@ describe('PoolListComponent', () => { }; beforeEach(() => { - spyOn(TestBed.inject(BsModalService), 'show').and.callFake((deletionClass, config) => { + spyOn(TestBed.inject(ModalService), 'show').and.callFake((deletionClass, initialState) => { return { - content: Object.assign(new deletionClass(), config.initialState) + componentInstance: Object.assign(new deletionClass(), initialState) }; }); spyOn(poolService, 'delete').and.stub(); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts index b0d63284b0ac3..590a2b5c60f8d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-list/pool-list.component.ts @@ -1,8 +1,8 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { ConfigurationService } from '../../../shared/api/configuration.service'; import { PoolService } from '../../../shared/api/pool.service'; @@ -21,6 +21,7 @@ import { FinishedTask } from '../../../shared/models/finished-task'; import { Permissions } from '../../../shared/models/permissions'; import { DimlessPipe } from '../../../shared/pipes/dimless.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { TaskListService } from '../../../shared/services/task-list.service'; import { TaskWrapperService } from '../../../shared/services/task-wrapper.service'; import { URLBuilderService } from '../../../shared/services/url-builder.service'; @@ -51,7 +52,7 @@ export class PoolListComponent extends ListWithDetails implements OnInit { pools: Pool[]; columns: CdTableColumn[]; selection = new CdTableSelection(); - modalRef: BsModalRef; + modalRef: NgbModalRef; executingTasks: ExecutingTask[] = []; permissions: Permissions; tableActions: CdTableAction[]; @@ -64,7 +65,7 @@ export class PoolListComponent extends ListWithDetails implements OnInit { private taskWrapper: TaskWrapperService, private authStorageService: AuthStorageService, private taskListService: TaskListService, - private modalService: BsModalService, + private modalService: ModalService, private i18n: I18n, private pgCategoryService: PgCategoryService, private dimlessPipe: DimlessPipe, @@ -221,15 +222,13 @@ export class PoolListComponent extends ListWithDetails implements OnInit { deletePoolModal() { const name = this.selection.first().pool_name; this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: 'Pool', - itemNames: [name], - submitActionObservable: () => - this.taskWrapper.wrapTaskAroundCall({ - task: new FinishedTask(`${BASE_URL}/${URLVerbs.DELETE}`, { pool_name: name }), - call: this.poolService.delete(name) - }) - } + itemDescription: 'Pool', + itemNames: [name], + submitActionObservable: () => + this.taskWrapper.wrapTaskAroundCall({ + task: new FinishedTask(`${BASE_URL}/${URLVerbs.DELETE}`, { pool_name: name }), + call: this.poolService.delete(name) + }) }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts index 4cc380c3d16ba..51bb131eb843e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.spec.ts @@ -4,7 +4,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; -import { ModalModule } from 'ngx-bootstrap/modal'; import { of } from 'rxjs'; import { @@ -29,7 +28,6 @@ describe('RgwBucketListComponent', () => { imports: [ BrowserAnimationsModule, RouterTestingModule, - ModalModule.forRoot(), SharedModule, NgbNavModule, HttpClientTestingModule diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts index cf7820b8edd65..83c1c8cb9ae93 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-list/rgw-bucket-list.component.ts @@ -9,7 +9,6 @@ import { import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs'; import { RgwBucketService } from '../../../shared/api/rgw-bucket.service'; @@ -26,6 +25,7 @@ import { Permission } from '../../../shared/models/permissions'; import { DimlessBinaryPipe } from '../../../shared/pipes/dimless-binary.pipe'; import { DimlessPipe } from '../../../shared/pipes/dimless.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { URLBuilderService } from '../../../shared/services/url-builder.service'; const BASE_URL = 'rgw/bucket'; @@ -57,7 +57,7 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit { private dimlessBinaryPipe: DimlessBinaryPipe, private dimlessPipe: DimlessPipe, private rgwBucketService: RgwBucketService, - private bsModalService: BsModalService, + private modalService: ModalService, private i18n: I18n, private urlBuilder: URLBuilderService, public actionLabels: ActionLabelsI18n, @@ -182,36 +182,34 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit { } deleteAction() { - this.bsModalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: this.selection.hasSingleSelection - ? this.i18n('bucket') - : this.i18n('buckets'), - itemNames: this.selection.selected.map((bucket: any) => bucket['bid']), - submitActionObservable: () => { - return new Observable((observer: Subscriber) => { - // 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) => { + // 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(); + } }); - } + }); } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html index de9165c309a29..e07155637f115 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.html @@ -1,4 +1,4 @@ - + {{ action | titlecase }} {{ resource | upperFirst }} @@ -64,7 +64,7 @@ {{ action | titlecase }} {{ resource | upperFirst }} - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts index c2b53d2620b13..9c457bec9c40c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; import { SharedModule } from '../../../shared/shared.module'; @@ -15,7 +15,7 @@ describe('RgwUserCapabilityModalComponent', () => { configureTestBed({ declarations: [RgwUserCapabilityModalComponent], imports: [ReactiveFormsModule, SharedModule, RouterTestingModule], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts index 50001eda91f22..cb4ca3855454d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-capability-modal/rgw-user-capability-modal.component.ts @@ -1,9 +1,9 @@ import { Component, EventEmitter, Output } from '@angular/core'; import { Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ActionLabelsI18n } from '../../../shared/constants/app.constants'; import { CdFormBuilder } from '../../../shared/forms/cd-form-builder'; @@ -32,7 +32,7 @@ export class RgwUserCapabilityModalComponent { constructor( private formBuilder: CdFormBuilder, - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private i18n: I18n, public actionLabels: ActionLabelsI18n ) { @@ -89,6 +89,6 @@ export class RgwUserCapabilityModalComponent { onSubmit() { const capability: RgwUserCapability = this.formGroup.value; this.submitAction.emit(capability); - this.bsModalRef.hide(); + this.activeModal.close(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts index 11a647690c3f7..9dcf79a3c034b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.spec.ts @@ -3,7 +3,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { configureTestBed, i18nProviders, TabHelper } from '../../../../testing/unit-test-helper'; import { SharedModule } from '../../../shared/shared.module'; @@ -17,7 +16,7 @@ describe('RgwUserDetailsComponent', () => { configureTestBed({ declarations: [RgwUserDetailsComponent], imports: [BrowserAnimationsModule, HttpClientTestingModule, SharedModule, NgbNavModule], - providers: [BsModalService, i18nProviders] + providers: [i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts index bfd5683d7097b..f2cd8faa18b9a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts @@ -2,12 +2,12 @@ import { Component, Input, OnChanges, OnInit, TemplateRef, ViewChild } from '@an import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { RgwUserService } from '../../../shared/api/rgw-user.service'; import { Icons } from '../../../shared/enum/icons.enum'; import { CdTableColumn } from '../../../shared/models/cd-table-column'; import { CdTableSelection } from '../../../shared/models/cd-table-selection'; +import { ModalService } from '../../../shared/services/modal.service'; import { RgwUserS3Key } from '../models/rgw-user-s3-key'; import { RgwUserSwiftKey } from '../models/rgw-user-swift-key'; import { RgwUserS3KeyModalComponent } from '../rgw-user-s3-key-modal/rgw-user-s3-key-modal.component'; @@ -40,7 +40,7 @@ export class RgwUserDetailsComponent implements OnChanges, OnInit { constructor( private rgwUserService: RgwUserService, - private bsModalService: BsModalService, + private modalService: ModalService, private i18n: I18n ) {} @@ -109,16 +109,16 @@ export class RgwUserDetailsComponent implements OnChanges, OnInit { showKeyModal() { const key = this.keysSelection.first(); - const modalRef = this.bsModalService.show( + const modalRef = this.modalService.show( key.type === 'S3' ? RgwUserS3KeyModalComponent : RgwUserSwiftKeyModalComponent ); switch (key.type) { case 'S3': - modalRef.content.setViewing(); - modalRef.content.setValues(key.ref.user, key.ref.access_key, key.ref.secret_key); + modalRef.componentInstance.setViewing(); + modalRef.componentInstance.setValues(key.ref.user, key.ref.access_key, key.ref.secret_key); break; case 'Swift': - modalRef.content.setValues(key.ref.user, key.ref.secret_key); + modalRef.componentInstance.setValues(key.ref.user, key.ref.secret_key); break; } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts index e297c330be08c..c41e7384d28b6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.spec.ts @@ -5,7 +5,6 @@ import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of as observableOf } from 'rxjs'; @@ -35,7 +34,7 @@ describe('RgwUserFormComponent', () => { ToastrModule.forRoot(), NgbTooltipModule ], - providers: [BsModalService, i18nProviders] + providers: [i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts index 44d1e1eddc94b..00a799f180f8d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-form/rgw-user-form.component.ts @@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { concat as observableConcat, forkJoin as observableForkJoin, Observable } from 'rxjs'; import { RgwUserService } from '../../../shared/api/rgw-user.service'; @@ -16,6 +15,7 @@ import { CdFormBuilder } from '../../../shared/forms/cd-form-builder'; import { CdFormGroup } from '../../../shared/forms/cd-form-group'; import { CdValidators, isEmptyInputValue } from '../../../shared/forms/cd-validators'; import { FormatterService } from '../../../shared/services/formatter.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { NotificationService } from '../../../shared/services/notification.service'; import { RgwUserCapabilities } from '../models/rgw-user-capabilities'; import { RgwUserCapability } from '../models/rgw-user-capability'; @@ -53,7 +53,7 @@ export class RgwUserFormComponent extends CdForm implements OnInit { private route: ActivatedRoute, private router: Router, private rgwUserService: RgwUserService, - private bsModalService: BsModalService, + private modalService: ModalService, private notificationService: NotificationService, private i18n: I18n, public actionLabels: ActionLabelsI18n @@ -468,19 +468,19 @@ export class RgwUserFormComponent extends CdForm implements OnInit { */ showSubuserModal(index?: number) { const uid = this.userForm.getValue('uid'); - const modalRef = this.bsModalService.show(RgwUserSubuserModalComponent); + const modalRef = this.modalService.show(RgwUserSubuserModalComponent); if (_.isNumber(index)) { // Edit const subuser = this.subusers[index]; - modalRef.content.setEditing(); - modalRef.content.setValues(uid, subuser.id, subuser.permissions); + modalRef.componentInstance.setEditing(); + modalRef.componentInstance.setValues(uid, subuser.id, subuser.permissions); } else { // Add - modalRef.content.setEditing(false); - modalRef.content.setValues(uid); - modalRef.content.setSubusers(this.subusers); + modalRef.componentInstance.setEditing(false); + modalRef.componentInstance.setValues(uid); + modalRef.componentInstance.setSubusers(this.subusers); } - modalRef.content.submitAction.subscribe((subuser: RgwUserSubuser) => { + modalRef.componentInstance.submitAction.subscribe((subuser: RgwUserSubuser) => { this.setSubuser(subuser, index); }); } @@ -490,18 +490,18 @@ export class RgwUserFormComponent extends CdForm implements OnInit { * @param {number | undefined} index The S3 key to show. */ showS3KeyModal(index?: number) { - const modalRef = this.bsModalService.show(RgwUserS3KeyModalComponent); + const modalRef = this.modalService.show(RgwUserS3KeyModalComponent); if (_.isNumber(index)) { // View const key = this.s3Keys[index]; - modalRef.content.setViewing(); - modalRef.content.setValues(key.user, key.access_key, key.secret_key); + modalRef.componentInstance.setViewing(); + modalRef.componentInstance.setValues(key.user, key.access_key, key.secret_key); } else { // Add const candidates = this._getS3KeyUserCandidates(); - modalRef.content.setViewing(false); - modalRef.content.setUserCandidates(candidates); - modalRef.content.submitAction.subscribe((key: RgwUserS3Key) => { + modalRef.componentInstance.setViewing(false); + modalRef.componentInstance.setUserCandidates(candidates); + modalRef.componentInstance.submitAction.subscribe((key: RgwUserS3Key) => { this.setS3Key(key); }); } @@ -512,9 +512,9 @@ export class RgwUserFormComponent extends CdForm implements OnInit { * @param {number} index The Swift key to show. */ showSwiftKeyModal(index: number) { - const modalRef = this.bsModalService.show(RgwUserSwiftKeyModalComponent); + const modalRef = this.modalService.show(RgwUserSwiftKeyModalComponent); const key = this.swiftKeys[index]; - modalRef.content.setValues(key.user, key.secret_key); + modalRef.componentInstance.setValues(key.user, key.secret_key); } /** @@ -522,18 +522,18 @@ export class RgwUserFormComponent extends CdForm implements OnInit { * @param {number | undefined} index The S3 key to show. */ showCapabilityModal(index?: number) { - const modalRef = this.bsModalService.show(RgwUserCapabilityModalComponent); + const modalRef = this.modalService.show(RgwUserCapabilityModalComponent); if (_.isNumber(index)) { // Edit const cap = this.capabilities[index]; - modalRef.content.setEditing(); - modalRef.content.setValues(cap.type, cap.perm); + modalRef.componentInstance.setEditing(); + modalRef.componentInstance.setValues(cap.type, cap.perm); } else { // Add - modalRef.content.setEditing(false); - modalRef.content.setCapabilities(this.capabilities); + modalRef.componentInstance.setEditing(false); + modalRef.componentInstance.setCapabilities(this.capabilities); } - modalRef.content.submitAction.subscribe((cap: RgwUserCapability) => { + modalRef.componentInstance.submitAction.subscribe((cap: RgwUserCapability) => { this.setCapability(cap, index); }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts index 12f7a1df2a06f..a893a0db1feaa 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.spec.ts @@ -4,8 +4,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { RouterTestingModule } from '@angular/router/testing'; -import { ModalModule } from 'ngx-bootstrap/modal'; - import { configureTestBed, i18nProviders, @@ -21,13 +19,7 @@ describe('RgwUserListComponent', () => { configureTestBed({ declarations: [RgwUserListComponent], - imports: [ - BrowserAnimationsModule, - RouterTestingModule, - HttpClientTestingModule, - ModalModule.forRoot(), - SharedModule - ], + imports: [BrowserAnimationsModule, RouterTestingModule, HttpClientTestingModule, SharedModule], schemas: [NO_ERRORS_SCHEMA], providers: i18nProviders }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts index 7688c84484c07..4bad8007d7d0a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-list/rgw-user-list.component.ts @@ -1,7 +1,6 @@ import { Component, NgZone, ViewChild } from '@angular/core'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs'; import { RgwUserService } from '../../../shared/api/rgw-user.service'; @@ -17,6 +16,7 @@ import { CdTableFetchDataContext } from '../../../shared/models/cd-table-fetch-d import { CdTableSelection } from '../../../shared/models/cd-table-selection'; import { Permission } from '../../../shared/models/permissions'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { URLBuilderService } from '../../../shared/services/url-builder.service'; const BASE_URL = 'rgw/user'; @@ -41,7 +41,7 @@ export class RgwUserListComponent extends ListWithDetails { constructor( private authStorageService: AuthStorageService, private rgwUserService: RgwUserService, - private bsModalService: BsModalService, + private modalService: ModalService, private i18n: I18n, private urlBuilder: URLBuilderService, public actionLabels: ActionLabelsI18n, @@ -139,34 +139,32 @@ export class RgwUserListComponent extends ListWithDetails { } deleteAction() { - this.bsModalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: this.selection.hasSingleSelection ? this.i18n('user') : this.i18n('users'), - itemNames: this.selection.selected.map((user: any) => user['uid']), - submitActionObservable: (): Observable => { - return new Observable((observer: Subscriber) => { - // 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 => { + return new Observable((observer: Subscriber) => { + // 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(); + } }); - } + }); } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html index b82f23070ff07..a6f73722dcebe 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.html @@ -1,4 +1,4 @@ - + {{ action | titlecase }} {{ resource | upperFirst }} @@ -123,7 +123,7 @@ (submitAction)="onSubmit()" i18n="form action button|Example: Create Pool@@formActionButton" [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }} - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts index bf8dcdce75109..0f124dcb2ff82 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; import { SharedModule } from '../../../shared/shared.module'; @@ -15,7 +15,7 @@ describe('RgwUserS3KeyModalComponent', () => { configureTestBed({ declarations: [RgwUserS3KeyModalComponent], imports: [ReactiveFormsModule, SharedModule, RouterTestingModule], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts index a3cd2f1167e43..bc762794d68d9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-s3-key-modal/rgw-user-s3-key-modal.component.ts @@ -1,9 +1,9 @@ import { Component, EventEmitter, Output } from '@angular/core'; import { Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ActionLabelsI18n } from '../../../shared/constants/app.constants'; import { CdFormBuilder } from '../../../shared/forms/cd-form-builder'; @@ -31,7 +31,7 @@ export class RgwUserS3KeyModalComponent { constructor( private formBuilder: CdFormBuilder, - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private i18n: I18n, public actionLabels: ActionLabelsI18n ) { @@ -81,6 +81,6 @@ export class RgwUserS3KeyModalComponent { onSubmit() { const key: RgwUserS3Key = this.formGroup.value; this.submitAction.emit(key); - this.bsModalRef.hide(); + this.activeModal.close(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html index 578324221e070..7ad3d10962d8f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.html @@ -125,7 +125,7 @@ {{ action | titlecase }} {{ resource | upperFirst }} - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts index a828c3d5df028..4c883468e7fb5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; import { SharedModule } from '../../../shared/shared.module'; @@ -15,7 +15,7 @@ describe('RgwUserSubuserModalComponent', () => { configureTestBed({ declarations: [RgwUserSubuserModalComponent], imports: [ReactiveFormsModule, SharedModule, RouterTestingModule], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts index 04623f8c26d3b..663c7f937794c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-subuser-modal/rgw-user-subuser-modal.component.ts @@ -1,9 +1,9 @@ import { Component, EventEmitter, Output } from '@angular/core'; import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ActionLabelsI18n } from '../../../shared/constants/app.constants'; import { CdFormBuilder } from '../../../shared/forms/cd-form-builder'; @@ -32,7 +32,7 @@ export class RgwUserSubuserModalComponent { constructor( private formBuilder: CdFormBuilder, - public bsModalRef: BsModalRef, + public bsModalRef: NgbActiveModal, private i18n: I18n, private actionLabels: ActionLabelsI18n ) { @@ -127,6 +127,6 @@ export class RgwUserSubuserModalComponent { subuser.generate_secret = values.generate_secret; subuser.secret_key = values.secret_key; this.submitAction.emit(subuser); - this.bsModalRef.hide(); + this.bsModalRef.close(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html index 5e74d7e3547a7..320d9d7f6048c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.html @@ -1,4 +1,4 @@ - + {{ action | titlecase }} {{ resource | upperFirst }} @@ -51,7 +51,7 @@ diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts index 38d9bde31a3ef..af2c873bcdb8a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.spec.ts @@ -2,7 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { ToastrModule } from 'ngx-toastr'; import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; @@ -16,7 +16,7 @@ describe('RgwUserSwiftKeyModalComponent', () => { configureTestBed({ declarations: [RgwUserSwiftKeyModalComponent], imports: [ToastrModule.forRoot(), FormsModule, SharedModule, RouterTestingModule], - providers: [BsModalRef, i18nProviders] + providers: [NgbActiveModal, i18nProviders] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts index ad10e070f7e6d..aa34f6b7c7f0b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-swift-key-modal/rgw-user-swift-key-modal.component.ts @@ -1,7 +1,7 @@ import { Component } from '@angular/core'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { ActionLabelsI18n } from '../../../shared/constants/app.constants'; @@ -17,7 +17,7 @@ export class RgwUserSwiftKeyModalComponent { action: string; constructor( - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private i18n: I18n, public actionLabels: ActionLabelsI18n ) { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts index 6396f5d59eb29..bef59ffb1dc4c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw.module.ts @@ -5,7 +5,6 @@ import { RouterModule, Routes } from '@angular/router'; import { NgbNavModule, NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap'; import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation'; -import { ModalModule } from 'ngx-bootstrap/modal'; import { ActionLabels, URLVerbs } from '../../shared/constants/app.constants'; import { AuthGuardService } from '../../shared/services/auth-guard.service'; @@ -33,7 +32,6 @@ import { RgwUserSwiftKeyModalComponent } from './rgw-user-swift-key-modal/rgw-us ReactiveFormsModule, PerformanceCounterModule, NgbNavModule, - ModalModule.forRoot(), RouterModule, NgBootstrapFormValidationModule, NgbTooltipModule diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts index daa96f34e8bfd..e162d3721dc28 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts @@ -25,8 +25,8 @@ describe('LoginComponent', () => { }); it('should ensure no modal dialogs are opened', () => { - component['bsModalService']['modalsCount'] = 2; + component['modalService']['modalsCount'] = 2; component.ngOnInit(); - expect(component['bsModalService'].getModalsCount()).toBe(0); + expect(component['modalService'].hasOpenModals()).toBeFalsy(); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts index 9286e31d30f10..0703268a0237d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts @@ -1,11 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { Router } from '@angular/router'; -import { BsModalService } from 'ngx-bootstrap/modal'; - import { AuthService } from '../../../shared/api/auth.service'; import { Credentials } from '../../../shared/models/credentials'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; @Component({ selector: 'cd-login', @@ -19,7 +18,7 @@ export class LoginComponent implements OnInit { constructor( private authService: AuthService, private authStorageService: AuthStorageService, - private bsModalService: BsModalService, + private modalService: ModalService, private router: Router ) {} @@ -30,10 +29,7 @@ export class LoginComponent implements OnInit { // Make sure all open modal dialogs are closed. This might be // necessary when the logged in user is redirected to the login // page after a 401. - const modalsCount = this.bsModalService.getModalsCount(); - for (let i = 1; i <= modalsCount; i++) { - this.bsModalService.hide(i); - } + this.modalService.dismissAll(); let token: string = null; if (window.location.hash.indexOf('access_token=') !== -1) { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts index 24e38b2d6b96c..e042a4f2f26fc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-form/role-form.component.ts @@ -4,7 +4,6 @@ import { ActivatedRoute, Router } from '@angular/router'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { forkJoin as observableForkJoin } from 'rxjs'; import { RoleService } from '../../../shared/api/role.service'; @@ -32,8 +31,6 @@ export class RoleFormComponent extends CdForm implements OnInit { @ViewChild('cellPermissionCheckboxTpl', { static: true }) cellPermissionCheckboxTpl: TemplateRef; - modalRef: BsModalRef; - roleForm: CdFormGroup; response: RoleFormModel; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts index a945b79fae4d9..f1cd8753868ee 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/role-list/role-list.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit } from '@angular/core'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { forkJoin } from 'rxjs'; import { RoleService } from '../../../shared/api/role.service'; @@ -19,6 +19,7 @@ import { CdTableSelection } from '../../../shared/models/cd-table-selection'; import { Permission } from '../../../shared/models/permissions'; import { EmptyPipe } from '../../../shared/pipes/empty.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { NotificationService } from '../../../shared/services/notification.service'; import { URLBuilderService } from '../../../shared/services/url-builder.service'; @@ -38,14 +39,14 @@ export class RoleListComponent extends ListWithDetails implements OnInit { scopes: Array; selection = new CdTableSelection(); - modalRef: BsModalRef; + modalRef: NgbModalRef; constructor( private roleService: RoleService, private scopeService: ScopeService, private emptyPipe: EmptyPipe, private authStorageService: AuthStorageService, - private modalService: BsModalService, + private modalService: ModalService, private notificationService: NotificationService, private i18n: I18n, private urlBuilder: URLBuilderService, @@ -124,14 +125,14 @@ export class RoleListComponent extends ListWithDetails implements OnInit { this.roleService.delete(role).subscribe( () => { this.getRoles(); - this.modalRef.hide(); + this.modalRef.close(); this.notificationService.show( NotificationType.success, this.i18n(`Deleted role '{{role_name}}'`, { role_name: role }) ); }, () => { - this.modalRef.content.stopLoadingSpinner(); + this.modalRef.componentInstance.stopLoadingSpinner(); } ); } @@ -139,41 +140,37 @@ export class RoleListComponent extends ListWithDetails implements OnInit { deleteRoleModal() { const name = this.selection.first().name; this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: 'Role', - itemNames: [name], - submitAction: () => this.deleteRole(name) - } + itemDescription: 'Role', + itemNames: [name], + submitAction: () => this.deleteRole(name) }); } cloneRole() { const name = this.selection.first().name; this.modalRef = this.modalService.show(FormModalComponent, { - initialState: { - fields: [ - { - type: 'text', - name: 'newName', - value: `${name}_clone`, - label: this.i18n('New name'), - required: true - } - ], - titleText: this.i18n('Clone Role'), - submitButtonText: this.i18n('Clone Role'), - onSubmit: (values: object) => { - this.roleService.clone(name, values['newName']).subscribe(() => { - this.getRoles(); - this.notificationService.show( - NotificationType.success, - this.i18n(`Cloned role '{{dst_name}}' from '{{src_name}}'`, { - src_name: name, - dst_name: values['newName'] - }) - ); - }); + fields: [ + { + type: 'text', + name: 'newName', + value: `${name}_clone`, + label: this.i18n('New name'), + required: true } + ], + titleText: this.i18n('Clone Role'), + submitButtonText: this.i18n('Clone Role'), + onSubmit: (values: object) => { + this.roleService.clone(name, values['newName']).subscribe(() => { + this.getRoles(); + this.notificationService.show( + NotificationType.success, + this.i18n(`Cloned role '{{dst_name}}' from '{{src_name}}'`, { + src_name: name, + dst_name: values['newName'] + }) + ); + }); } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts index df3bc8b08d4eb..3d79fc97a84dc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.spec.ts @@ -7,7 +7,6 @@ import { RouterTestingModule } from '@angular/router/testing'; import { ButtonsModule } from 'ngx-bootstrap/buttons'; import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; -import { BsModalService } from 'ngx-bootstrap/modal'; import { ToastrModule } from 'ngx-toastr'; import { of } from 'rxjs'; @@ -19,6 +18,7 @@ import { ComponentsModule } from '../../../shared/components/components.module'; import { LoadingPanelComponent } from '../../../shared/components/loading-panel/loading-panel.component'; import { CdFormGroup } from '../../../shared/forms/cd-form-group'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { NotificationService } from '../../../shared/services/notification.service'; import { SharedModule } from '../../../shared/shared.module'; import { PasswordPolicyService } from './../../../shared/services/password-policy.service'; @@ -31,7 +31,7 @@ describe('UserFormComponent', () => { let fixture: ComponentFixture; let httpTesting: HttpTestingController; let userService: UserService; - let modalService: BsModalService; + let modalService: ModalService; let router: Router; let formHelper: FormHelper; @@ -70,7 +70,7 @@ describe('UserFormComponent', () => { form = component.userForm; httpTesting = TestBed.inject(HttpTestingController); userService = TestBed.inject(UserService); - modalService = TestBed.inject(BsModalService); + modalService = TestBed.inject(ModalService); router = TestBed.inject(Router); spyOn(router, 'navigate'); fixture.detectChanges(); @@ -221,8 +221,8 @@ describe('UserFormComponent', () => { it('should alert if user is removing needed role permission', () => { spyOn(TestBed.inject(AuthStorageService), 'getUsername').and.callFake(() => user.username); let modalBodyTpl = null; - spyOn(modalService, 'show').and.callFake((_content, config) => { - modalBodyTpl = config.initialState.bodyTpl; + spyOn(modalService, 'show').and.callFake((_content, initialState) => { + modalBodyTpl = initialState.bodyTpl; }); formHelper.setValue('roles', ['read-only']); component.submit(); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts index 9bd83ac16758d..1489b433b53c2 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-form/user-form.component.ts @@ -2,9 +2,9 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { Validators } from '@angular/forms'; import { ActivatedRoute, Router } from '@angular/router'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { forkJoin as observableForkJoin } from 'rxjs'; import { AuthService } from '../../../shared/api/auth.service'; @@ -22,6 +22,7 @@ import { CdFormGroup } from '../../../shared/forms/cd-form-group'; import { CdValidators } from '../../../shared/forms/cd-validators'; import { CdPwdExpirationSettings } from '../../../shared/models/cd-pwd-expiration-settings'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { NotificationService } from '../../../shared/services/notification.service'; import { PasswordPolicyService } from '../../../shared/services/password-policy.service'; import { UserFormMode } from './user-form-mode.enum'; @@ -37,7 +38,7 @@ export class UserFormComponent extends CdForm implements OnInit { @ViewChild('removeSelfUserReadUpdatePermissionTpl', { static: true }) removeSelfUserReadUpdatePermissionTpl: TemplateRef; - modalRef: BsModalRef; + modalRef: NgbModalRef; userForm: CdFormGroup; response: UserFormModel; @@ -64,7 +65,7 @@ export class UserFormComponent extends CdForm implements OnInit { private authStorageService: AuthStorageService, private route: ActivatedRoute, public router: Router, - private modalService: BsModalService, + private modalService: ModalService, private roleService: RoleService, private userService: UserService, private notificationService: NotificationService, @@ -226,7 +227,7 @@ export class UserFormComponent extends CdForm implements OnInit { buttonText: this.i18n('Continue'), bodyTpl: this.removeSelfUserReadUpdatePermissionTpl, onSubmit: () => { - this.modalRef.hide(); + this.modalRef.close(); this.doEditAction(); }, onCancel: () => { @@ -234,7 +235,7 @@ export class UserFormComponent extends CdForm implements OnInit { this.userForm.get('roles').reset(this.userForm.get('roles').value); } }; - this.modalRef = this.modalService.show(ConfirmationModalComponent, { initialState }); + this.modalRef = this.modalService.show(ConfirmationModalComponent, initialState); } else { this.doEditAction(); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts index 9f2a6207f0702..53e031a5d5965 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/auth/user-list/user-list.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; import { UserService } from '../../../shared/api/user.service'; import { CriticalConfirmationModalComponent } from '../../../shared/components/critical-confirmation-modal/critical-confirmation-modal.component'; @@ -16,6 +16,7 @@ import { Permission } from '../../../shared/models/permissions'; import { CdDatePipe } from '../../../shared/pipes/cd-date.pipe'; import { EmptyPipe } from '../../../shared/pipes/empty.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { NotificationService } from '../../../shared/services/notification.service'; import { URLBuilderService } from '../../../shared/services/url-builder.service'; @@ -39,12 +40,12 @@ export class UserListComponent implements OnInit { users: Array; selection = new CdTableSelection(); - modalRef: BsModalRef; + modalRef: NgbModalRef; constructor( private userService: UserService, private emptyPipe: EmptyPipe, - private modalService: BsModalService, + private modalService: ModalService, private notificationService: NotificationService, private authStorageService: AuthStorageService, private i18n: I18n, @@ -134,14 +135,14 @@ export class UserListComponent implements OnInit { this.userService.delete(username).subscribe( () => { this.getUsers(); - this.modalRef.hide(); + this.modalRef.close(); this.notificationService.show( NotificationType.success, this.i18n(`Deleted user '{{username}}'`, { username: username }) ); }, () => { - this.modalRef.content.stopLoadingSpinner(); + this.modalRef.componentInstance.stopLoadingSpinner(); } ); } @@ -157,12 +158,11 @@ export class UserListComponent implements OnInit { ); return; } + this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - itemDescription: 'User', - itemNames: [username], - submitAction: () => this.deleteUser(username) - } + itemDescription: 'User', + itemNames: [username], + submitAction: () => this.deleteUser(username) }); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html index 8727b8dcc3ad2..2ac7476e39066 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.html @@ -3,7 +3,7 @@ diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts index 996accd2230b1..a636f7fbe1062 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.spec.ts @@ -1,7 +1,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { BehaviorSubject } from 'rxjs'; import { configureTestBed } from '../../../../testing/unit-test-helper'; @@ -30,7 +30,7 @@ describe('AboutComponent', () => { configureTestBed({ imports: [SharedModule, HttpClientTestingModule], declarations: [AboutComponent], - providers: [BsModalRef, { provide: SummaryService, useClass: SummaryServiceMock }] + providers: [NgbActiveModal, { provide: SummaryService, useClass: SummaryServiceMock }] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts index 6b77c8f94ee3f..6f885a9e6e816 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/about/about.component.ts @@ -1,7 +1,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { detect } from 'detect-browser'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { Subscription } from 'rxjs'; import { environment } from '../../../../environments/environment'; @@ -28,7 +28,7 @@ export class AboutComponent implements OnInit, OnDestroy { copyright: string; constructor( - public modalRef: BsModalRef, + public activeModal: NgbActiveModal, private summaryService: SummaryService, private userService: UserService, private authStorageService: AuthStorageService diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts index e6821ddf960ff..8ec1046662939 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/dashboard-help/dashboard-help.component.ts @@ -1,10 +1,11 @@ import { Component, OnInit, ViewChild } from '@angular/core'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; +import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { Icons } from '../../../shared/enum/icons.enum'; import { CephReleaseNamePipe } from '../../../shared/pipes/ceph-release-name.pipe'; import { AuthStorageService } from '../../../shared/services/auth-storage.service'; +import { ModalService } from '../../../shared/services/modal.service'; import { SummaryService } from '../../../shared/services/summary.service'; import { AboutComponent } from '../about/about.component'; @@ -17,13 +18,13 @@ export class DashboardHelpComponent implements OnInit { @ViewChild('docsForm', { static: true }) docsFormElement: any; docsUrl: string; - modalRef: BsModalRef; + modalRef: NgbModalRef; icons = Icons; constructor( private summaryService: SummaryService, private cephReleaseNamePipe: CephReleaseNamePipe, - private modalService: BsModalService, + private modalService: ModalService, private authStorageService: AuthStorageService ) {} @@ -35,8 +36,7 @@ export class DashboardHelpComponent implements OnInit { } openAboutModal() { - this.modalRef = this.modalService.show(AboutComponent); - this.modalRef.setClass('modal-lg'); + this.modalRef = this.modalService.show(AboutComponent, null, { size: 'lg' }); } goToApiDocs() { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts index 55a2779a04026..5b615dbcb5c21 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts @@ -13,7 +13,6 @@ import { import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation'; import { ClickOutsideModule } from 'ng-click-outside'; import { ChartsModule } from 'ng2-charts'; -import { ModalModule } from 'ngx-bootstrap/modal'; import { SimplebarAngularModule } from 'simplebar-angular'; import { DirectivesModule } from '../directives/directives.module'; @@ -54,7 +53,6 @@ import { ViewCacheComponent } from './view-cache/view-cache.component'; ChartsModule, ReactiveFormsModule, PipesModule, - ModalModule.forRoot(), DirectivesModule, NgbDropdownModule, NgBootstrapFormValidationModule, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts index d64a56d146058..c66910a5ea2fc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.spec.ts @@ -4,14 +4,14 @@ import { ReactiveFormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { RouterTestingModule } from '@angular/router/testing'; -import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal'; +import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed, FixtureHelper, - i18nProviders, - modalServiceShow + i18nProviders } from '../../../../testing/unit-test-helper'; +import { ModalService } from '../../services/modal.service'; import { BackButtonComponent } from '../back-button/back-button.component'; import { ModalComponent } from '../modal/modal.component'; import { SubmitButtonComponent } from '../submit-button/submit-button.component'; @@ -30,15 +30,16 @@ export class MockModule {} class MockComponent { @ViewChild('fillTpl', { static: true }) fillTpl: TemplateRef; - modalRef: BsModalRef; + modalRef: NgbModalRef; returnValue: any; // Normally private, but public is needed by tests - constructor(public modalService: BsModalService) {} + constructor(public modalService: ModalService) {} private openModal(extendBaseState = {}) { - this.modalRef = this.modalService.show(ConfirmationModalComponent, { - initialState: Object.assign( + this.modalRef = this.modalService.show( + ConfirmationModalComponent, + Object.assign( { titleText: 'Title is a must have', buttonText: 'Action label', @@ -46,12 +47,11 @@ class MockComponent { description: 'String based description.', onSubmit: () => { this.returnValue = 'The submit action has to hide manually.'; - this.modalRef.hide(); } }, extendBaseState ) - }); + ); } basicModal() { @@ -70,17 +70,8 @@ describe('ConfirmationModalComponent', () => { let fixture: ComponentFixture; let mockComponent: MockComponent; let mockFixture: ComponentFixture; - let modalService: BsModalService; let fh: FixtureHelper; - /** - * The hide method of `BsModalService` doesn't emit events during tests that's why it's mocked. - * - * The only events of hide are `null`, `'backdrop-click'` and `'esc'` as described here: - * https://ngx-universal.herokuapp.com/#/modals#service-events - */ - const hide = (x: string) => modalService.onHide.emit(null || x); - const expectReturnValue = (v: string) => expect(mockComponent.returnValue).toBe(v); configureTestBed({ @@ -92,8 +83,8 @@ describe('ConfirmationModalComponent', () => { SubmitButtonComponent ], schemas: [NO_ERRORS_SCHEMA], - imports: [ModalModule.forRoot(), ReactiveFormsModule, MockModule, RouterTestingModule], - providers: [BsModalRef, i18nProviders, SubmitButtonComponent] + imports: [ReactiveFormsModule, MockModule, RouterTestingModule, NgbModalModule], + providers: [NgbActiveModal, i18nProviders, SubmitButtonComponent] }); beforeEach(() => { @@ -101,14 +92,14 @@ describe('ConfirmationModalComponent', () => { mockFixture = TestBed.createComponent(MockComponent); mockComponent = mockFixture.componentInstance; mockFixture.detectChanges(); - modalService = TestBed.inject(BsModalService); - spyOn(modalService, 'show').and.callFake((_modalComp, config) => { - const data = modalServiceShow(ConfirmationModalComponent, config); - fixture = data.fixture; - component = data.component; - spyOn(component.modalRef, 'hide').and.callFake(hide); + + spyOn(TestBed.inject(ModalService), 'show').and.callFake((_modalComp, config) => { + fixture = TestBed.createComponent(ConfirmationModalComponent); + component = fixture.componentInstance; + component = Object.assign(component, config); + component.activeModal = { close: () => true } as any; + spyOn(component.activeModal, 'close').and.callThrough(); fh.updateFixture(fixture); - return data.ref; }); }); @@ -165,7 +156,7 @@ describe('ConfirmationModalComponent', () => { describe('basics', () => { beforeEach(() => { mockComponent.basicModal(); - spyOn(mockComponent.modalRef, 'hide').and.callFake(hide); + spyOn(component, 'onSubmit').and.callThrough(); }); it('should show the correct title', () => { @@ -183,15 +174,15 @@ describe('ConfirmationModalComponent', () => { 'focusButton' ); fh.clickElement('.tc_submitButton'); - expect(mockComponent.modalRef.hide).toHaveBeenCalledTimes(1); - expect(component.modalRef.hide).toHaveBeenCalledTimes(0); + expect(component.onSubmit).toHaveBeenCalledTimes(1); + expect(component.activeModal.close).toHaveBeenCalledTimes(0); expectReturnValue('The submit action has to hide manually.'); }); it('should use the default cancel action', () => { fh.clickElement('.tc_backButton'); - expect(mockComponent.modalRef.hide).toHaveBeenCalledTimes(0); - expect(component.modalRef.hide).toHaveBeenCalledTimes(1); + expect(component.onSubmit).toHaveBeenCalledTimes(0); + expect(component.activeModal.close).toHaveBeenCalledTimes(1); expectReturnValue(undefined); }); @@ -201,38 +192,4 @@ describe('ConfirmationModalComponent', () => { ); }); }); - - describe('custom cancel action', () => { - const expectCancelValue = () => - expectReturnValue('If you have todo something besides hiding the modal.'); - - beforeEach(() => { - mockComponent.customCancelModal(); - }); - - it('should use custom cancel action', () => { - fh.clickElement('.tc_backButton'); - expectCancelValue(); - }); - - it('should use custom cancel action if escape was pressed', () => { - hide('esc'); - expectCancelValue(); - }); - - it('should use custom cancel action if clicked outside the modal', () => { - hide('backdrop-click'); - expectCancelValue(); - }); - - it('should unsubscribe on destroy', () => { - hide('backdrop-click'); - expectCancelValue(); - const s = 'This value will not be changed.'; - mockComponent.returnValue = s; - component.ngOnDestroy(); - hide('backdrop-click'); - expectReturnValue(s); - }); - }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts index 87383eedff3d7..bdd233cefc1ce 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts @@ -1,8 +1,7 @@ import { Component, OnDestroy, OnInit, TemplateRef } from '@angular/core'; import { FormGroup } from '@angular/forms'; -import { BsModalRef, BsModalService } from 'ngx-bootstrap/modal'; -import { Subscription } from 'rxjs'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'cd-confirmation-modal', @@ -27,16 +26,10 @@ export class ConfirmationModalComponent implements OnInit, OnDestroy { // Component only boundCancel = this.cancel.bind(this); confirmationForm: FormGroup; - private onHide: Subscription; private canceled = false; - constructor(public modalRef: BsModalRef, private modalService: BsModalService) { + constructor(public activeModal: NgbActiveModal) { this.confirmationForm = new FormGroup({}); - this.onHide = this.modalService.onHide.subscribe((e: any) => { - if (this.onCancel && (e || this.canceled)) { - this.onCancel(); - } - }); } ngOnInit() { @@ -54,12 +47,14 @@ export class ConfirmationModalComponent implements OnInit, OnDestroy { } ngOnDestroy() { - this.onHide.unsubscribe(); + if (this.onCancel && this.canceled) { + this.onCancel(); + } } cancel() { this.canceled = true; - this.modalRef.hide(); + this.activeModal.close(); } stopLoadingSpinner() { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html index ed834b0897f71..4d70814547674 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.html @@ -1,5 +1,5 @@ + [modalRef]="activeModal"> @@ -47,7 +47,7 @@ (submitAction)="callSubmitAction()"> - diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts index f0a7cb7c4c375..3223256e9b9b7 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.spec.ts @@ -1,13 +1,13 @@ import { Component, NgModule, NO_ERRORS_SCHEMA, TemplateRef, ViewChild } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { NgForm, ReactiveFormsModule } from '@angular/forms'; -import { By } from '@angular/platform-browser'; -import { BsModalRef, BsModalService, ModalModule } from 'ngx-bootstrap/modal'; +import { NgbActiveModal, NgbModalModule, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { Observable, Subscriber, timer as observableTimer } from 'rxjs'; import { configureTestBed, modalServiceShow } from '../../../../testing/unit-test-helper'; import { DirectivesModule } from '../../directives/directives.module'; +import { ModalService } from '../../services/modal.service'; import { AlertPanelComponent } from '../alert-panel/alert-panel.component'; import { LoadingPanelComponent } from '../loading-panel/loading-panel.component'; import { CriticalConfirmationModalComponent } from './critical-confirmation-modal.component'; @@ -40,27 +40,23 @@ class MockComponent { modalDescription: TemplateRef; someData = [1, 2, 3, 4, 5]; finished: number[]; - ctrlRef: BsModalRef; - modalRef: BsModalRef; + ctrlRef: NgbModalRef; + modalRef: NgbModalRef; // Normally private - public was needed for the tests - constructor(public modalService: BsModalService) {} + constructor(public modalService: ModalService) {} openCtrlDriven() { this.ctrlRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - submitAction: this.fakeDeleteController.bind(this), - bodyTemplate: this.ctrlDescription - } + submitAction: this.fakeDeleteController.bind(this), + bodyTemplate: this.ctrlDescription }); } openModalDriven() { this.modalRef = this.modalService.show(CriticalConfirmationModalComponent, { - initialState: { - submitActionObservable: this.fakeDelete(), - bodyTemplate: this.modalDescription - } + submitActionObservable: this.fakeDelete(), + bodyTemplate: this.modalDescription }); } @@ -82,7 +78,7 @@ class MockComponent { fakeDeleteController() { observableTimer(100).subscribe(() => { this.finish(); - this.ctrlRef.hide(); + this.ctrlRef.close(); }); } } @@ -91,28 +87,29 @@ describe('CriticalConfirmationModalComponent', () => { let mockComponent: MockComponent; let component: CriticalConfirmationModalComponent; let mockFixture: ComponentFixture; - let fixture: ComponentFixture; - - configureTestBed({ - declarations: [ - MockComponent, - CriticalConfirmationModalComponent, - LoadingPanelComponent, - AlertPanelComponent - ], - schemas: [NO_ERRORS_SCHEMA], - imports: [ModalModule.forRoot(), ReactiveFormsModule, MockModule, DirectivesModule], - providers: [BsModalRef] - }); + + configureTestBed( + { + declarations: [ + MockComponent, + CriticalConfirmationModalComponent, + LoadingPanelComponent, + AlertPanelComponent + ], + schemas: [NO_ERRORS_SCHEMA], + imports: [ReactiveFormsModule, MockModule, DirectivesModule, NgbModalModule], + providers: [NgbActiveModal] + }, + [CriticalConfirmationModalComponent] + ); beforeEach(() => { mockFixture = TestBed.createComponent(MockComponent); mockComponent = mockFixture.componentInstance; spyOn(mockComponent.modalService, 'show').and.callFake((_modalComp, config) => { const data = modalServiceShow(CriticalConfirmationModalComponent, config); - fixture = data.fixture; - component = data.component; - return data.ref; + component = data.componentInstance; + return data; }); mockComponent.openCtrlDriven(); mockFixture.detectChanges(); @@ -122,18 +119,6 @@ describe('CriticalConfirmationModalComponent', () => { expect(component).toBeTruthy(); }); - it('should focus the checkbox form field', (done) => { - fixture.detectChanges(); - fixture.whenStable().then(() => { - const focused = fixture.debugElement.query(By.css(':focus')); - expect(focused.attributes.id).toBe('confirmation'); - expect(focused.attributes.type).toBe('checkbox'); - const element = document.getElementById('confirmation'); - expect(element === document.activeElement).toBeTruthy(); - done(); - }); - }); - it('should throw an error if no action is defined', () => { component = Object.assign(component, { submitAction: null, @@ -161,16 +146,16 @@ describe('CriticalConfirmationModalComponent', () => { ctrl.setValue(value); ctrl.markAsDirty(); ctrl.updateValueAndValidity(); - fixture.detectChanges(); + mockFixture.detectChanges(); }; it('should test hideModal', () => { - expect(component.modalRef).toBeTruthy(); + expect(component.activeModal).toBeTruthy(); expect(component.hideModal).toBeTruthy(); - spyOn(component.modalRef, 'hide').and.callThrough(); - expect(component.modalRef.hide).not.toHaveBeenCalled(); + spyOn(component.activeModal, 'close').and.callThrough(); + expect(component.activeModal.close).not.toHaveBeenCalled(); component.hideModal(); - expect(component.modalRef.hide).toHaveBeenCalled(); + expect(component.activeModal.close).toHaveBeenCalled(); }); describe('validate confirmation', () => { @@ -204,7 +189,7 @@ describe('CriticalConfirmationModalComponent', () => { describe('Controller driven', () => { beforeEach(() => { spyOn(component, 'submitAction').and.callThrough(); - spyOn(mockComponent.ctrlRef, 'hide').and.callThrough(); + spyOn(mockComponent.ctrlRef, 'close').and.callThrough(); }); it('should test fake deletion that closes modal', fakeAsync(() => { @@ -214,13 +199,13 @@ describe('CriticalConfirmationModalComponent', () => { component.callSubmitAction(); expect(component.stopLoadingSpinner).not.toHaveBeenCalled(); expect(component.hideModal).not.toHaveBeenCalled(); - expect(mockComponent.ctrlRef.hide).not.toHaveBeenCalled(); + expect(mockComponent.ctrlRef.close).not.toHaveBeenCalled(); expect(component.submitAction).toHaveBeenCalled(); expect(mockComponent.finished).toBe(undefined); // After deletionCall tick(2000); expect(component.hideModal).not.toHaveBeenCalled(); - expect(mockComponent.ctrlRef.hide).toHaveBeenCalled(); + expect(mockComponent.ctrlRef.close).toHaveBeenCalled(); expect(mockComponent.finished).toEqual([6, 7, 8, 9]); })); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts index 5dfe0caee42c5..a929b7dde86f5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component.ts @@ -1,7 +1,7 @@ import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core'; import { FormControl, Validators } from '@angular/forms'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { Observable } from 'rxjs'; import { CdFormGroup } from '../../forms/cd-form-group'; @@ -27,7 +27,7 @@ export class CriticalConfirmationModalComponent implements OnInit { childFormGroup: CdFormGroup; childFormGroupTemplate: TemplateRef; - constructor(public modalRef: BsModalRef) {} + constructor(public activeModal: NgbActiveModal) {} ngOnInit() { const controls = { @@ -54,7 +54,7 @@ export class CriticalConfirmationModalComponent implements OnInit { } hideModal() { - this.modalRef.hide(); + this.activeModal.close(); } stopLoadingSpinner() { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html index 2ccb7893f64b4..f1f4b7f573f6a 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.html @@ -1,4 +1,4 @@ - + {{ titleText }} @@ -64,7 +64,7 @@ (submitAction)="onSubmitForm(formGroup.value)"> {{ submitButtonText }} - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts index 227076c1bdb0c..fbf10aa4594ee 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.spec.ts @@ -2,8 +2,8 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ReactiveFormsModule, Validators } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { NgBootstrapFormValidationModule } from 'ng-bootstrap-form-validation'; -import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal'; import { configureTestBed, @@ -53,13 +53,12 @@ describe('InputModalComponent', () => { configureTestBed({ imports: [ - ModalModule.forRoot(), NgBootstrapFormValidationModule.forRoot(), RouterTestingModule, ReactiveFormsModule, SharedModule ], - providers: [i18nProviders, BsModalRef] + providers: [i18nProviders, NgbActiveModal] }); beforeEach(() => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts index 7bc5d06b7caf5..a401794122909 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/form-modal/form-modal.component.ts @@ -1,9 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { FormControl, ValidatorFn, Validators } from '@angular/forms'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { I18n } from '@ngx-translate/i18n-polyfill'; import * as _ from 'lodash'; -import { BsModalRef } from 'ngx-bootstrap/modal'; import { CdFormBuilder } from '../../forms/cd-form-builder'; import { CdFormGroup } from '../../forms/cd-form-group'; @@ -28,7 +28,7 @@ export class FormModalComponent implements OnInit { formGroup: CdFormGroup; constructor( - public bsModalRef: BsModalRef, + public activeModal: NgbActiveModal, private formBuilder: CdFormBuilder, private formatter: FormatterService, private dimlessBinaryPipe: DimlessBinaryPipe, @@ -104,7 +104,7 @@ export class FormModalComponent implements OnInit { values[key] = this.formatter.toBytes(value); } }); - this.bsModalRef.hide(); + this.activeModal.close(); if (_.isFunction(this.onSubmit)) { this.onSubmit(values); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss index 5a7248f537740..73ce56b9920a0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.scss @@ -15,3 +15,7 @@ overflow-y: auto; overflow-x: hidden; } + +button.close { + outline: none; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts index a43ece29029c3..86c55beff4f7c 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.spec.ts @@ -1,6 +1,6 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { BsModalRef, ModalModule } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { configureTestBed } from '../../../../testing/unit-test-helper'; import { ModalComponent } from './modal.component'; @@ -10,7 +10,6 @@ describe('ModalComponent', () => { let fixture: ComponentFixture; configureTestBed({ - imports: [ModalModule.forRoot()], declarations: [ModalComponent] }); @@ -34,9 +33,9 @@ describe('ModalComponent', () => { }); it('should hide the modal', () => { - component.modalRef = new BsModalRef(); - spyOn(component.modalRef, 'hide'); + component.modalRef = new NgbActiveModal(); + spyOn(component.modalRef, 'close'); component.close(); - expect(component.modalRef.hide).toHaveBeenCalled(); + expect(component.modalRef.close).toHaveBeenCalled(); }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts index 47cc5d7456683..730da6d62527b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/modal/modal.component.ts @@ -1,6 +1,6 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; -import { BsModalRef } from 'ngx-bootstrap/modal'; +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; @Component({ selector: 'cd-modal', @@ -9,7 +9,7 @@ import { BsModalRef } from 'ngx-bootstrap/modal'; }) export class ModalComponent { @Input() - modalRef: BsModalRef; + modalRef: NgbActiveModal; /** * Should be a function that is triggered when the modal is hidden. @@ -18,9 +18,7 @@ export class ModalComponent { hide = new EventEmitter(); close() { - if (this.modalRef) { - this.modalRef.hide(); - } + this.modalRef?.close(); this.hide.emit(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-modal/orchestrator-doc-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-modal/orchestrator-doc-modal.component.html index a205f714eed26..338be7df6dc19 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-modal/orchestrator-doc-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/orchestrator-doc-modal/orchestrator-doc-modal.component.html @@ -1,4 +1,4 @@ - + {{ actionDescription }} {{ itemDescription }} @@ -7,7 +7,7 @@