]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: improve edit site name action in rbd-mirroring 46639/head
authorNizamudeen A <nia@redhat.com>
Mon, 13 Jun 2022 08:24:15 +0000 (13:54 +0530)
committerNizamudeen A <nia@redhat.com>
Thu, 16 Jun 2022 09:33:58 +0000 (15:03 +0530)
Fixes: https://tracker.ceph.com/issues/55896
Signed-off-by: Nizamudeen A <nia@redhat.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html [deleted file]
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.scss [deleted file]
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.spec.ts [deleted file]
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.ts [deleted file]
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/mirroring.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/overview/overview.component.ts

diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.html
deleted file mode 100644 (file)
index f0c9197..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-<cd-modal [modalRef]="activeModal">
-  <ng-container i18n
-                class="modal-title">Edit site name</ng-container>
-
-  <ng-container class="modal-content">
-    <form name="editSiteNameForm"
-          class="form"
-          #formDir="ngForm"
-          [formGroup]="editSiteNameForm"
-          novalidate>
-      <div class="modal-body">
-        <p>
-          <ng-container i18n>Edit the site name and click&nbsp;
-          <kbd>Update</kbd>.</ng-container>
-        </p>
-
-        <div class="form-group">
-          <label class="col-form-label required"
-                 for="siteName"
-                 i18n>Site Name</label>
-          <input class="form-control"
-                 type="text"
-                 placeholder="Name..."
-                 i18n-placeholder
-                 id="siteName"
-                 name="siteName"
-                 formControlName="siteName"
-                 autofocus>
-        </div>
-      </div>
-
-      <div class="modal-footer">
-        <cd-form-button-panel (submitActionEvent)="update()"
-                              [form]="editSiteNameForm"
-                              [submitText]="actionLabels.UPDATE"></cd-form-button-panel>
-      </div>
-    </form>
-  </ng-container>
-</cd-modal>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.scss
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.spec.ts
deleted file mode 100644 (file)
index 193e4f0..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-import { HttpClientTestingModule } from '@angular/common/http/testing';
-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 { ToastrModule } from 'ngx-toastr';
-import { of } from 'rxjs';
-
-import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
-import { NotificationService } from '~/app/shared/services/notification.service';
-import { SharedModule } from '~/app/shared/shared.module';
-import { configureTestBed } from '~/testing/unit-test-helper';
-import { EditSiteNameModalComponent } from './edit-site-name-modal.component';
-
-describe('EditSiteNameModalComponent', () => {
-  let component: EditSiteNameModalComponent;
-  let fixture: ComponentFixture<EditSiteNameModalComponent>;
-  let notificationService: NotificationService;
-  let rbdMirroringService: RbdMirroringService;
-
-  configureTestBed({
-    declarations: [EditSiteNameModalComponent],
-    imports: [
-      HttpClientTestingModule,
-      ReactiveFormsModule,
-      RouterTestingModule,
-      SharedModule,
-      ToastrModule.forRoot()
-    ],
-    providers: [NgbActiveModal]
-  });
-
-  beforeEach(() => {
-    fixture = TestBed.createComponent(EditSiteNameModalComponent);
-    component = fixture.componentInstance;
-    component.siteName = 'site-A';
-
-    notificationService = TestBed.inject(NotificationService);
-    spyOn(notificationService, 'show').and.stub();
-
-    rbdMirroringService = TestBed.inject(RbdMirroringService);
-  });
-
-  it('should create', () => {
-    expect(component).toBeTruthy();
-  });
-
-  describe('edit site name', () => {
-    beforeEach(() => {
-      spyOn(rbdMirroringService, 'getSiteName').and.callFake(() => of({ site_name: 'site-A' }));
-      spyOn(rbdMirroringService, 'refresh').and.stub();
-      spyOn(component.activeModal, 'close').and.callThrough();
-      fixture.detectChanges();
-    });
-
-    afterEach(() => {
-      expect(rbdMirroringService.getSiteName).toHaveBeenCalledTimes(1);
-      expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
-      expect(component.activeModal.close).toHaveBeenCalledTimes(1);
-    });
-
-    it('should call setSiteName', () => {
-      spyOn(rbdMirroringService, 'setSiteName').and.callFake(() => of({ site_name: 'new-site-A' }));
-
-      component.editSiteNameForm.patchValue({
-        siteName: 'new-site-A'
-      });
-      component.update();
-      expect(rbdMirroringService.setSiteName).toHaveBeenCalledWith('new-site-A');
-    });
-  });
-});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/edit-site-name-modal/edit-site-name-modal.component.ts
deleted file mode 100644 (file)
index aa43bd0..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-import { Component, OnInit } from '@angular/core';
-import { FormControl } from '@angular/forms';
-
-import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
-
-import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
-import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
-import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
-import { FinishedTask } from '~/app/shared/models/finished-task';
-import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
-
-@Component({
-  selector: 'cd-edit-site-mode-modal',
-  templateUrl: './edit-site-name-modal.component.html',
-  styleUrls: ['./edit-site-name-modal.component.scss']
-})
-export class EditSiteNameModalComponent implements OnInit {
-  siteName: string;
-
-  editSiteNameForm: CdFormGroup;
-
-  constructor(
-    public activeModal: NgbActiveModal,
-    public actionLabels: ActionLabelsI18n,
-    private rbdMirroringService: RbdMirroringService,
-    private taskWrapper: TaskWrapperService
-  ) {
-    this.createForm();
-  }
-
-  createForm() {
-    this.editSiteNameForm = new CdFormGroup({
-      siteName: new FormControl('', {})
-    });
-  }
-
-  ngOnInit() {
-    this.editSiteNameForm.get('siteName').setValue(this.siteName);
-    this.rbdMirroringService.getSiteName().subscribe((response: any) => {
-      this.editSiteNameForm.get('siteName').setValue(response.site_name);
-    });
-  }
-
-  update() {
-    const action = this.taskWrapper.wrapTaskAroundCall({
-      task: new FinishedTask('rbd/mirroring/site_name/edit', {}),
-      call: this.rbdMirroringService.setSiteName(this.editSiteNameForm.getValue('siteName'))
-    });
-
-    action.subscribe({
-      error: () => this.editSiteNameForm.setErrors({ cdSubmitButton: true }),
-      complete: () => {
-        this.rbdMirroringService.refresh();
-        this.activeModal.close();
-      }
-    });
-  }
-}
index 0edea02494ca765b6209b8013958a5c4f34c7ad2..dfebe934f1e0fac1aadd73d49d77cb894a29ba40 100644 (file)
@@ -9,7 +9,6 @@ import { SharedModule } from '~/app/shared/shared.module';
 import { BootstrapCreateModalComponent } from './bootstrap-create-modal/bootstrap-create-modal.component';
 import { BootstrapImportModalComponent } from './bootstrap-import-modal/bootstrap-import-modal.component';
 import { DaemonListComponent } from './daemon-list/daemon-list.component';
-import { EditSiteNameModalComponent } from './edit-site-name-modal/edit-site-name-modal.component';
 import { ImageListComponent } from './image-list/image-list.component';
 import { MirrorHealthColorPipe } from './mirror-health-color.pipe';
 import { OverviewComponent } from './overview/overview.component';
@@ -31,7 +30,6 @@ import { PoolListComponent } from './pool-list/pool-list.component';
     BootstrapCreateModalComponent,
     BootstrapImportModalComponent,
     DaemonListComponent,
-    EditSiteNameModalComponent,
     ImageListComponent,
     OverviewComponent,
     PoolEditModeModalComponent,
index 7bd0bf017b370f2b710452290a5dd5b156c73c87..9cdfab939cc2aa529b97a0efd4fe1d744c91f0fa 100644 (file)
@@ -1,11 +1,43 @@
 <div class="row">
   <div class="col-md-12">
-    <span><strong i18n>Site Name:</strong> {{siteName}}</span>
-    <cd-table-actions class="table-actions float-right"
-                      [permission]="permission"
-                      [selection]="selection"
-                      [tableActions]="tableActions">
-    </cd-table-actions>
+    <form name="rbdmirroringForm"
+          #formDir="ngForm"
+          [formGroup]="rbdmirroringForm"
+          novalidate>
+
+      <div class="d-flex flex-row">
+        <label class="col-form-label"
+               for="siteName"
+               i18n>Site Name</label>
+
+        <div class="col-md-4 input-group mb-3 mr-auto">
+          <input type="text"
+                 class="form-control"
+                 id="siteName"
+                 name="siteName"
+                 formControlName="siteName"
+                 [attr.disabled]="!editing ? true : null">
+          <div class="input-group-append">
+            <button class="btn btn-light"
+                    id="editSiteName"
+                    (click)="updateSiteName()">
+              <i [ngClass]="icons.edit"
+                 *ngIf="!editing"></i>
+              <i [ngClass]="icons.check"
+                 *ngIf="editing"></i>
+            </button>
+            <cd-copy-2-clipboard-button [source]="siteName"
+                                        [byId]="false">
+            </cd-copy-2-clipboard-button>
+          </div>
+        </div>
+        <cd-table-actions class="table-actions"
+                          [permission]="permission"
+                          [selection]="selection"
+                          [tableActions]="tableActions">
+        </cd-table-actions>
+      </div>
+    </form>
   </div>
 </div>
 
index a3c83a75d967be922e0e857a5c3b315d5e496d0e..d771c2f70034a15e7bc09fb7d193f96f047c6f0a 100644 (file)
@@ -1,11 +1,14 @@
 import { HttpClientTestingModule } from '@angular/common/http/testing';
 import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { ReactiveFormsModule } from '@angular/forms';
 import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 
 import { NgbNavModule, NgbProgressbarModule } from '@ng-bootstrap/ng-bootstrap';
 import { ToastrModule } from 'ngx-toastr';
+import { of } from 'rxjs';
 
+import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
 import { SharedModule } from '~/app/shared/shared.module';
 import { configureTestBed } from '~/testing/unit-test-helper';
 import { DaemonListComponent } from '../daemon-list/daemon-list.component';
@@ -17,6 +20,7 @@ import { OverviewComponent } from './overview.component';
 describe('OverviewComponent', () => {
   let component: OverviewComponent;
   let fixture: ComponentFixture<OverviewComponent>;
+  let rbdMirroringService: RbdMirroringService;
 
   configureTestBed({
     declarations: [
@@ -33,6 +37,7 @@ describe('OverviewComponent', () => {
       NgbProgressbarModule,
       HttpClientTestingModule,
       RouterTestingModule,
+      ReactiveFormsModule,
       ToastrModule.forRoot()
     ]
   });
@@ -40,10 +45,35 @@ describe('OverviewComponent', () => {
   beforeEach(() => {
     fixture = TestBed.createComponent(OverviewComponent);
     component = fixture.componentInstance;
+    rbdMirroringService = TestBed.inject(RbdMirroringService);
+    component.siteName = 'site-A';
     fixture.detectChanges();
   });
 
   it('should create', () => {
     expect(component).toBeTruthy();
   });
+
+  describe('edit site name', () => {
+    beforeEach(() => {
+      spyOn(rbdMirroringService, 'getSiteName').and.callFake(() => of({ site_name: 'site-A' }));
+      spyOn(rbdMirroringService, 'refresh').and.stub();
+      fixture.detectChanges();
+    });
+
+    afterEach(() => {
+      expect(rbdMirroringService.refresh).toHaveBeenCalledTimes(1);
+    });
+
+    it('should call setSiteName', () => {
+      component.editing = true;
+      spyOn(rbdMirroringService, 'setSiteName').and.callFake(() => of({ site_name: 'new-site-A' }));
+
+      component.rbdmirroringForm.patchValue({
+        siteName: 'new-site-A'
+      });
+      component.updateSiteName();
+      expect(rbdMirroringService.setSiteName).toHaveBeenCalledWith('new-site-A');
+    });
+  });
 });
index c919e03cdbb82680370a4ab4a603a1f19e4641f4..3ee1fa81334285d4ee56b38533e4bf9662bf5d9e 100644 (file)
@@ -1,4 +1,5 @@
 import { Component, OnDestroy, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
 
 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import { Subscription } from 'rxjs';
@@ -7,14 +8,16 @@ import { Pool } from '~/app/ceph/pool/pool';
 import { RbdMirroringService } from '~/app/shared/api/rbd-mirroring.service';
 import { Icons } from '~/app/shared/enum/icons.enum';
 import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum';
+import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
 import { CdTableAction } from '~/app/shared/models/cd-table-action';
 import { CdTableSelection } from '~/app/shared/models/cd-table-selection';
+import { FinishedTask } from '~/app/shared/models/finished-task';
 import { Permission } from '~/app/shared/models/permissions';
 import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
 import { ModalService } from '~/app/shared/services/modal.service';
+import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
 import { BootstrapCreateModalComponent } from '../bootstrap-create-modal/bootstrap-create-modal.component';
 import { BootstrapImportModalComponent } from '../bootstrap-import-modal/bootstrap-import-modal.component';
-import { EditSiteNameModalComponent } from '../edit-site-name-modal/edit-site-name-modal.component';
 
 @Component({
   selector: 'cd-mirroring',
@@ -22,6 +25,7 @@ import { EditSiteNameModalComponent } from '../edit-site-name-modal/edit-site-na
   styleUrls: ['./overview.component.scss']
 })
 export class OverviewComponent implements OnInit, OnDestroy {
+  rbdmirroringForm: CdFormGroup;
   permission: Permission;
   tableActions: CdTableAction[];
   selection = new CdTableSelection();
@@ -30,27 +34,24 @@ export class OverviewComponent implements OnInit, OnDestroy {
   siteName: any;
   status: ViewCacheStatus;
   private subs = new Subscription();
+  editing = false;
+
+  icons = Icons;
 
   constructor(
     private authStorageService: AuthStorageService,
     private rbdMirroringService: RbdMirroringService,
-    private modalService: ModalService
+    private modalService: ModalService,
+    private taskWrapper: TaskWrapperService
   ) {
     this.permission = this.authStorageService.getPermissions().rbdMirroring;
 
-    const editSiteNameAction: CdTableAction = {
-      permission: 'update',
-      icon: Icons.edit,
-      click: () => this.editSiteNameModal(),
-      name: $localize`Edit Site Name`,
-      canBePrimary: () => true,
-      disable: () => false
-    };
     const createBootstrapAction: CdTableAction = {
       permission: 'update',
       icon: Icons.upload,
       click: () => this.createBootstrapModal(),
       name: $localize`Create Bootstrap Token`,
+      canBePrimary: () => true,
       disable: () => false
     };
     const importBootstrapAction: CdTableAction = {
@@ -60,30 +61,49 @@ export class OverviewComponent implements OnInit, OnDestroy {
       name: $localize`Import Bootstrap Token`,
       disable: () => this.peersExist
     };
-    this.tableActions = [editSiteNameAction, createBootstrapAction, importBootstrapAction];
+    this.tableActions = [createBootstrapAction, importBootstrapAction];
   }
 
   ngOnInit() {
+    this.createForm();
     this.subs.add(this.rbdMirroringService.startPolling());
     this.subs.add(
       this.rbdMirroringService.subscribeSummary((data) => {
         this.status = data.content_data.status;
-        this.siteName = data.site_name;
 
         this.peersExist = !!data.content_data.pools.find((o: Pool) => o['peer_uuids'].length > 0);
       })
     );
+    this.rbdMirroringService.getSiteName().subscribe((response: any) => {
+      this.siteName = response.site_name;
+      this.rbdmirroringForm.get('siteName').setValue(this.siteName);
+    });
+  }
+
+  private createForm() {
+    this.rbdmirroringForm = new CdFormGroup({
+      siteName: new FormControl({ value: '', disabled: true })
+    });
   }
 
   ngOnDestroy(): void {
     this.subs.unsubscribe();
   }
 
-  editSiteNameModal() {
-    const initialState = {
-      siteName: this.siteName
-    };
-    this.modalRef = this.modalService.show(EditSiteNameModalComponent, initialState);
+  updateSiteName() {
+    if (this.editing) {
+      const action = this.taskWrapper.wrapTaskAroundCall({
+        task: new FinishedTask('rbd/mirroring/site_name/edit', {}),
+        call: this.rbdMirroringService.setSiteName(this.rbdmirroringForm.getValue('siteName'))
+      });
+
+      action.subscribe({
+        complete: () => {
+          this.rbdMirroringService.refresh();
+        }
+      });
+    }
+    this.editing = !this.editing;
   }
 
   createBootstrapModal() {