+++ /dev/null
-<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
- <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>
+++ /dev/null
-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');
- });
- });
-});
+++ /dev/null
-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();
- }
- });
- }
-}
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';
BootstrapCreateModalComponent,
BootstrapImportModalComponent,
DaemonListComponent,
- EditSiteNameModalComponent,
ImageListComponent,
OverviewComponent,
PoolEditModeModalComponent,
<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>
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';
describe('OverviewComponent', () => {
let component: OverviewComponent;
let fixture: ComponentFixture<OverviewComponent>;
+ let rbdMirroringService: RbdMirroringService;
configureTestBed({
declarations: [
NgbProgressbarModule,
HttpClientTestingModule,
RouterTestingModule,
+ ReactiveFormsModule,
ToastrModule.forRoot()
]
});
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');
+ });
+ });
});
import { Component, OnDestroy, OnInit } from '@angular/core';
+import { FormControl } from '@angular/forms';
import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { Subscription } from 'rxjs';
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',
styleUrls: ['./overview.component.scss']
})
export class OverviewComponent implements OnInit, OnDestroy {
+ rbdmirroringForm: CdFormGroup;
permission: Permission;
tableActions: CdTableAction[];
selection = new CdTableSelection();
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 = {
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() {