From: Nizamudeen A Date: Mon, 9 Aug 2021 07:52:51 +0000 (+0530) Subject: mgr/dashboard: Refresh button on the iscsi targets page X-Git-Tag: v16.2.6~58^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=eea44f6e486adcbbd6a4b54d5ed2d28238854a13;p=ceph.git mgr/dashboard: Refresh button on the iscsi targets page Added a refresh button on the iscsi targets page. I've noticed that the auto reload causes some load on the backend. So I disabled the auto reload and went for the same approach as we have on rgw. A yellow warning color on refresh btn to let the user know to manually refresh that whenever needed. Fixes: https://tracker.ceph.com/issues/52102 Signed-off-by: Nizamudeen A (cherry picked from commit 8f23a587a8ccc686b1e3acbfa587fcab76bee45d) --- diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html index 0103c11249a1..f6ac54538e10 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.html @@ -23,6 +23,9 @@ forceIdentifier="true" selectionType="single" [hasDetails]="true" + [autoReload]="false" + [status]="tableStatus" + (fetchData)="getTargets()" (setExpandedRow)="setExpandedRow($event)" (updateSelection)="updateSelection($event)">
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts index 4459f2519e61..51998cf0b9e1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-list/iscsi-target-list.component.spec.ts @@ -56,6 +56,7 @@ describe('IscsiTargetListComponent', () => { spyOn(iscsiService, 'status').and.returnValue(of({ available: true })); spyOn(iscsiService, 'version').and.returnValue(of({ ceph_iscsi_config_version: 11 })); + spyOn(component, 'setTableRefreshTimeout').and.stub(); }); it('should create', () => { @@ -84,6 +85,12 @@ describe('IscsiTargetListComponent', () => { summaryService['summaryDataSource'].error(undefined); expect(component.table.reset).toHaveBeenCalled(); }); + + it('should call settings on the getTargets methods', () => { + spyOn(iscsiService, 'settings').and.callThrough(); + component.getTargets(); + expect(iscsiService.settings).toHaveBeenCalled(); + }); }); describe('handling of executing tasks', () => { 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 96b76d6b749e..d0eed6a72c77 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,4 +1,4 @@ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { Component, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import _ from 'lodash'; @@ -64,9 +64,10 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, private notAvailablePipe: NotAvailablePipe, private modalService: ModalService, private taskWrapper: TaskWrapperService, - public actionLabels: ActionLabelsI18n + public actionLabels: ActionLabelsI18n, + protected ngZone: NgZone ) { - super(); + super(ngZone); this.permission = this.authStorageService.getPermissions().iscsi; this.tableActions = [ @@ -124,29 +125,34 @@ export class IscsiTargetListComponent extends ListWithDetails implements OnInit, this.iscsiService.status().subscribe((result: any) => { this.available = result.available; - if (result.available) { - this.iscsiService.version().subscribe((res: any) => { - this.cephIscsiConfigVersion = res['ceph_iscsi_config_version']; - this.taskListService.init( - () => this.iscsiService.listTargets(), - (resp) => this.prepareResponse(resp), - (targets) => (this.targets = targets), - () => this.onFetchError(), - this.taskFilter, - this.itemFilter, - this.builders - ); - }); - - this.iscsiService.settings().subscribe((settings: any) => { - this.settings = settings; - }); - } else { + if (!result.available) { this.status = result.message; } }); } + getTargets() { + if (this.available) { + this.setTableRefreshTimeout(); + this.iscsiService.version().subscribe((res: any) => { + this.cephIscsiConfigVersion = res['ceph_iscsi_config_version']; + }); + this.taskListService.init( + () => this.iscsiService.listTargets(), + (resp) => this.prepareResponse(resp), + (targets) => (this.targets = targets), + () => this.onFetchError(), + this.taskFilter, + this.itemFilter, + this.builders + ); + + this.iscsiService.settings().subscribe((settings: any) => { + this.settings = settings; + }); + } + } + ngOnDestroy() { if (this.summaryDataSubscription) { this.summaryDataSubscription.unsubscribe(); 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 94dc9f070a15..ff0705793176 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 @@ -36,7 +36,7 @@ describe('RgwBucketListComponent', () => { rgwBucketServiceListSpy.and.returnValue(of([])); fixture = TestBed.createComponent(RgwBucketListComponent); component = fixture.componentInstance; - spyOn(component, 'timeConditionReached').and.stub(); + spyOn(component, 'setTableRefreshTimeout').and.stub(); fixture.detectChanges(); }); 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 0355e4808a3c..515a0697dbc6 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 @@ -5,7 +5,6 @@ import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs'; import { RgwBucketService } from '~/app/shared/api/rgw-bucket.service'; import { ListWithDetails } from '~/app/shared/classes/list-with-details.class'; -import { TableStatus } from '~/app/shared/classes/table-status'; import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component'; import { ActionLabelsI18n } from '~/app/shared/constants/app.constants'; import { TableComponent } from '~/app/shared/datatable/table/table.component'; @@ -42,7 +41,6 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit { columns: CdTableColumn[] = []; buckets: object[] = []; selection: CdTableSelection = new CdTableSelection(); - tableStatus = new TableStatus(); staleTimeout: number; constructor( @@ -53,9 +51,9 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit { private modalService: ModalService, private urlBuilder: URLBuilderService, public actionLabels: ActionLabelsI18n, - private ngZone: NgZone + protected ngZone: NgZone ) { - super(); + super(ngZone); } ngOnInit() { @@ -120,7 +118,7 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit { canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection }; this.tableActions = [addAction, editAction, deleteAction]; - this.timeConditionReached(); + this.setTableRefreshTimeout(); } transformBucketData() { @@ -140,23 +138,8 @@ export class RgwBucketListComponent extends ListWithDetails implements OnInit { }); } - timeConditionReached() { - clearTimeout(this.staleTimeout); - this.ngZone.runOutsideAngular(() => { - this.staleTimeout = window.setTimeout(() => { - this.ngZone.run(() => { - this.tableStatus = new TableStatus( - 'warning', - $localize`The bucket list data might be stale. If needed, you can manually reload it.` - ); - }); - }, 10000); - }); - } - getBucketList(context: CdTableFetchDataContext) { - this.tableStatus = new TableStatus(); - this.timeConditionReached(); + this.setTableRefreshTimeout(); this.rgwBucketService.list().subscribe( (resp: object[]) => { this.buckets = resp; 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 379957d88ec7..2f886ccf5d4a 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 @@ -30,7 +30,7 @@ describe('RgwUserListComponent', () => { rgwUserServiceListSpy.and.returnValue(of([])); fixture = TestBed.createComponent(RgwUserListComponent); component = fixture.componentInstance; - spyOn(component, 'timeConditionReached').and.stub(); + spyOn(component, 'setTableRefreshTimeout').and.stub(); fixture.detectChanges(); }); 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 e7f47298ecff..e48aaa7c4064 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 @@ -5,7 +5,6 @@ import { forkJoin as observableForkJoin, Observable, Subscriber } from 'rxjs'; import { RgwUserService } from '~/app/shared/api/rgw-user.service'; import { ListWithDetails } from '~/app/shared/classes/list-with-details.class'; -import { TableStatus } from '~/app/shared/classes/table-status'; import { CriticalConfirmationModalComponent } from '~/app/shared/components/critical-confirmation-modal/critical-confirmation-modal.component'; import { ActionLabelsI18n } from '~/app/shared/constants/app.constants'; import { TableComponent } from '~/app/shared/datatable/table/table.component'; @@ -40,7 +39,6 @@ export class RgwUserListComponent extends ListWithDetails implements OnInit { columns: CdTableColumn[] = []; users: object[] = []; selection: CdTableSelection = new CdTableSelection(); - tableStatus = new TableStatus(); staleTimeout: number; constructor( @@ -49,9 +47,9 @@ export class RgwUserListComponent extends ListWithDetails implements OnInit { private modalService: ModalService, private urlBuilder: URLBuilderService, public actionLabels: ActionLabelsI18n, - private ngZone: NgZone + protected ngZone: NgZone ) { - super(); + super(ngZone); } ngOnInit() { @@ -131,26 +129,11 @@ export class RgwUserListComponent extends ListWithDetails implements OnInit { canBePrimary: (selection: CdTableSelection) => selection.hasMultiSelection }; this.tableActions = [addAction, editAction, deleteAction]; - this.timeConditionReached(); - } - - timeConditionReached() { - clearTimeout(this.staleTimeout); - this.ngZone.runOutsideAngular(() => { - this.staleTimeout = window.setTimeout(() => { - this.ngZone.run(() => { - this.tableStatus = new TableStatus( - 'warning', - $localize`The user list data might be stale. If needed, you can manually reload it.` - ); - }); - }, 10000); - }); + this.setTableRefreshTimeout(); } getUserList(context: CdTableFetchDataContext) { - this.tableStatus = new TableStatus(); - this.timeConditionReached(); + this.setTableRefreshTimeout(); this.rgwUserService.list().subscribe( (resp: object[]) => { this.users = resp; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts index 585742622417..2eaeeb35eecf 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts @@ -1,7 +1,29 @@ +import { NgZone } from '@angular/core'; + +import { TableStatus } from './table-status'; + export class ListWithDetails { expandedRow: any; + staleTimeout: number; + tableStatus: TableStatus; + + constructor(protected ngZone?: NgZone) {} setExpandedRow(expandedRow: any) { this.expandedRow = expandedRow; } + + setTableRefreshTimeout() { + clearTimeout(this.staleTimeout); + this.ngZone.runOutsideAngular(() => { + this.staleTimeout = window.setTimeout(() => { + this.ngZone.run(() => { + this.tableStatus = new TableStatus( + 'warning', + $localize`The user list data might be stale. If needed, you can manually reload it.` + ); + }); + }, 10000); + }); + } }