diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts index b99a485b4edf6..f91a8ff837680 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.spec.ts @@ -203,6 +203,37 @@ describe('HostsComponent', () => { expect(spans[7].textContent).toBe('N/A'); }); + it('should test if memory/raw capacity columns shows N/A if facts are available but in fetching state', () => { + const features = [OrchestratorFeature.HOST_FACTS]; + let hostPayload: any[]; + hostPayload = [ + { + hostname: 'host_test', + services: [ + { + type: 'osd', + id: '0' + } + ], + cpu_count: 2, + cpu_cores: 1, + memory_total_kb: undefined, + hdd_count: 4, + hdd_capacity_bytes: undefined, + flash_count: 4, + flash_capacity_bytes: undefined, + nic_count: 1 + } + ]; + OrchestratorHelper.mockStatus(true, features); + hostListSpy.and.callFake(() => of(hostPayload)); + fixture.detectChanges(); + + component.getHosts(new CdTableFetchDataContext(() => undefined)); + expect(component.hosts[0]['memory_total_bytes']).toEqual('N/A'); + expect(component.hosts[0]['raw_capacity']).toEqual('N/A'); + }); + it('should show force maintenance modal when it is safe to stop host', () => { const errorMsg = `WARNING: Stopping 1 out of 1 daemons in Grafana service. Service will not be operational with no daemons left. At diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts index dfdcd8edef403..36bcf8ec8f046 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts @@ -27,6 +27,7 @@ import { OrchestratorFeature } from '~/app/shared/models/orchestrator.enum'; import { OrchestratorStatus } from '~/app/shared/models/orchestrator.interface'; import { Permissions } from '~/app/shared/models/permissions'; import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe'; +import { EmptyPipe } from '~/app/shared/pipes/empty.pipe'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { ModalService } from '~/app/shared/services/modal.service'; import { NotificationService } from '~/app/shared/services/notification.service'; @@ -109,6 +110,7 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit constructor( private authStorageService: AuthStorageService, private dimlessBinary: DimlessBinaryPipe, + private emptyPipe: EmptyPipe, private hostService: HostService, private actionLabels: ActionLabelsI18n, private modalService: ModalService, @@ -464,8 +466,10 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit transformHostsData() { if (this.checkHostsFactsAvailable()) { _.forEach(this.hosts, (hostKey) => { - hostKey['memory_total_bytes'] = hostKey['memory_total_kb'] * 1024; - hostKey['raw_capacity'] = hostKey['hdd_capacity_bytes'] + hostKey['flash_capacity_bytes']; + hostKey['memory_total_bytes'] = this.emptyPipe.transform(hostKey['memory_total_kb'] * 1024); + hostKey['raw_capacity'] = this.emptyPipe.transform( + hostKey['hdd_capacity_bytes'] + hostKey['flash_capacity_bytes'] + ); }); } else { // mark host facts columns unavailable diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts index fb753e8d9ac48..2b4df2e3c4fc8 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/empty.pipe.ts @@ -7,6 +7,11 @@ import _ from 'lodash'; }) export class EmptyPipe implements PipeTransform { transform(value: any): any { - return _.isUndefined(value) || _.isNull(value) ? '-' : value; + if (_.isUndefined(value) || _.isNull(value)) { + return '-'; + } else if (_.isNaN(value)) { + return 'N/A'; + } + return value; } }