From c940c431e009b10abcffc352eb7b0e8b39419189 Mon Sep 17 00:00:00 2001 From: Afreen Misbah Date: Tue, 26 Aug 2025 22:03:54 +0530 Subject: [PATCH] mgr/dashboard: Drop support for older version of dashboard Fixes https://tracker.ceph.com/issues/72739 - remove the code for previous version of dashboard - popover css was globally added in infocard component which needs to be removed now. So include css in respective components- dashboard and upgrade. Signed-off-by: Afreen Misbah --- .../cluster/upgrade/upgrade.component.scss | 14 + .../dashboard/dashboard-v3.component.scss | 43 +++ .../app/ceph/dashboard/dashboard.module.ts | 20 +- .../dashboard/dashboard.component.html | 11 +- .../dashboard/dashboard.component.scss | 3 - .../dashboard/dashboard.component.ts | 10 +- .../dashboard/health/health.component.html | 247 ------------- .../dashboard/health/health.component.scss | 45 --- .../dashboard/health/health.component.spec.ts | 348 ------------------ .../ceph/dashboard/health/health.component.ts | 281 -------------- .../info-card/info-card-popover.scss | 55 --- .../info-card/info-card.component.html | 18 - .../info-card/info-card.component.scss | 45 --- .../info-card/info-card.component.spec.ts | 65 ---- .../info-card/info-card.component.ts | 17 - .../info-group/info-group.component.html | 17 - .../info-group/info-group.component.scss | 14 - .../info-group/info-group.component.spec.ts | 36 -- .../info-group/info-group.component.ts | 14 - .../mds-dashboard-summary.pipe.spec.ts | 72 ---- .../dashboard/mds-dashboard-summary.pipe.ts | 78 ---- .../mgr-dashboard-summary.pipe.spec.ts | 52 --- .../dashboard/mgr-dashboard-summary.pipe.ts | 48 --- .../ceph/dashboard/mon-summary.pipe.spec.ts | 40 -- .../app/ceph/dashboard/mon-summary.pipe.ts | 17 - .../osd-dashboard-summary.pipe.spec.ts | 193 ---------- .../dashboard/osd-dashboard-summary.pipe.ts | 91 ----- .../shared/components/components.module.ts | 3 - .../refresh-selector.component.html | 19 - .../refresh-selector.component.scss | 0 .../refresh-selector.component.spec.ts | 27 -- .../refresh-selector.component.ts | 32 -- .../services/feature-toggles.service.ts | 1 - .../mgr/dashboard/frontend/src/styles.scss | 1 - src/pybind/mgr/dashboard/openapi.yaml | 4 - .../mgr/dashboard/plugins/feature_toggles.py | 2 - 36 files changed, 61 insertions(+), 1922 deletions(-) delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts delete mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/upgrade/upgrade.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/upgrade/upgrade.component.scss index e69de29bb2d1..3a9a1506c33b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/upgrade/upgrade.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/upgrade/upgrade.component.scss @@ -0,0 +1,14 @@ +@use './src/styles/vendor/variables' as vv; + +.info-card-content-clickable { + border: 1px solid vv.$gray-200; + border-radius: 3px; + cursor: pointer; + font-size: 1.25em; + padding: 7px; +} + +.info-card-content-clickable:hover { + background-color: vv.$gray-200; + border-color: vv.$gray-400; +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard/dashboard-v3.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard/dashboard-v3.component.scss index 49ab49bc81b5..28fb5afdb258 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard/dashboard-v3.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard/dashboard-v3.component.scss @@ -1,3 +1,5 @@ +@use './src/styles/vendor/variables' as vv; + .details { font-size: larger; @@ -31,3 +33,44 @@ white-space: normal; } } + +.info-card-popover-cluster-status { + max-height: 20vh; + max-width: 23vw; + + .popover-body { + font-size: 1rem; + max-height: 19vh; + max-width: 100%; + overflow: auto; + + li { + span { + font-size: 1.1em; + font-weight: bold; + } + + span.health-warn-description { + color: vv.$health-color-warning-800 !important; + } + } + } +} + +@media (max-width: vv.$screen-lg-max) { + .info-card-popover-cluster-status { + max-width: 31vw; + } +} + +@media (max-width: vv.$screen-md-max) { + .info-card-popover-cluster-status { + max-width: 46vw; + } +} + +@media (max-width: vv.$screen-sm-max) { + .info-card-popover-cluster-status { + max-width: 83vw; + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts index fdcdaa762a6c..b338a7b863af 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts @@ -12,13 +12,6 @@ import { CephSharedModule } from '../shared/ceph-shared.module'; import { FeedbackComponent } from '../shared/feedback/feedback.component'; import { DashboardComponent } from './dashboard/dashboard.component'; import { HealthPieComponent } from './health-pie/health-pie.component'; -import { HealthComponent } from './health/health.component'; -import { InfoCardComponent } from './info-card/info-card.component'; -import { InfoGroupComponent } from './info-group/info-group.component'; -import { MdsDashboardSummaryPipe } from './mds-dashboard-summary.pipe'; -import { MgrDashboardSummaryPipe } from './mgr-dashboard-summary.pipe'; -import { MonSummaryPipe } from './mon-summary.pipe'; -import { osdDashboardSummaryPipe } from './osd-dashboard-summary.pipe'; import { ToggletipModule } from 'carbon-components-angular'; @NgModule({ @@ -34,18 +27,7 @@ import { ToggletipModule } from 'carbon-components-angular'; BaseChartDirective, ToggletipModule ], - declarations: [ - HealthComponent, - DashboardComponent, - MonSummaryPipe, - osdDashboardSummaryPipe, - MgrDashboardSummaryPipe, - MdsDashboardSummaryPipe, - HealthPieComponent, - InfoCardComponent, - InfoGroupComponent, - FeedbackComponent - ], + declarations: [DashboardComponent, HealthPieComponent, FeedbackComponent], providers: [provideCharts(withDefaultRegisterables())] }) export class DashboardModule {} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html index 87b8c3376dc8..ea7ff2831988 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html @@ -2,14 +2,7 @@ skip to content - - - - - - - + - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss index 62c4af1dd92c..e69de29bb2d1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.scss @@ -1,3 +0,0 @@ -main:has(cd-health) { - padding-top: 20px; -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts index 021c945a2f58..e18b06df0333 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts @@ -1,16 +1,8 @@ import { Component } from '@angular/core'; -import { Observable } from 'rxjs'; -import { FeatureTogglesService } from '~/app/shared/services/feature-toggles.service'; @Component({ selector: 'cd-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.scss'] }) -export class DashboardComponent { - enabledFeature$: Observable; - - constructor(private featureToggles: FeatureTogglesService) { - this.enabledFeature$ = this.featureToggles.get(); - } -} +export class DashboardComponent {} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html deleted file mode 100644 index b015c7323361..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.html +++ /dev/null @@ -1,247 +0,0 @@ -
- - - - - -
- - {{ healthData.health.status | healthLabel | uppercase }} - - -
-
-
- -
-
-
-
- -
- {{ healthData?.health.status | healthLabel | uppercase }} -
-
-
- - - {{ healthData?.hosts }} total - - - - {{ healthData?.mon_status | monSummary }} - - - - - {{ result.content }} - - - - - - {{ result.content }} - - - - - {{ healthData?.rgw }} total - - - - - - {{ result.content }} - - - - - {{ healthData?.iscsi_daemons.up + healthData?.iscsi_daemons.down }} total - - {{ healthData?.iscsi_daemons.up }} up, - {{ healthData?.iscsi_daemons.down }} - down - -
- - - - - - - - - - - - - -
- -
- - -
- -
- -
    -
  • - {{ pgStatesText.key }}: {{ pgStatesText.value }} -
  • -
-
-
-
-
- - - {{ healthData?.pools.length }} - - - - {{ healthData?.pg_info.pgs_per_osd | dimless }} - -
- - - - - - - - - - - - - - {{ (healthData?.client_perf.recovering_bytes_per_sec | dimlessBinary) + '/s' }} - - - - {{ healthData?.scrub_status }} - - - - - - - - -
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss deleted file mode 100644 index def7aab11a6e..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.scss +++ /dev/null @@ -1,45 +0,0 @@ -@use './src/styles/vendor/variables' as vv; - -cd-info-card { - padding: 0 0.5vw; -} - -::ng-deep cd-health .pg-status-popover-wrapper { - position: relative; - - .popover { - max-height: 20vh; - max-width: unset !important; - min-width: unset !important; - position: absolute; - width: 116%; - - .popover-body { - font-size: 1rem; - max-height: 19vh; - max-width: 100%; - } - } -} - -.logs-link { - text-align: center; - - a { - color: vv.$primary; - } -} - -.card-text-error { - color: vv.$chart-danger; - display: inline; -} - -.card-text-line-break::after { - content: '\A'; - white-space: pre; -} - -.popover-info:hover { - cursor: pointer; -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts deleted file mode 100644 index 4b8a4167ad2f..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.spec.ts +++ /dev/null @@ -1,348 +0,0 @@ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; - -import _ from 'lodash'; -import { of } from 'rxjs'; - -import { PgCategoryService } from '~/app/ceph/shared/pg-category.service'; -import { HealthService } from '~/app/shared/api/health.service'; -import { CssHelper } from '~/app/shared/classes/css-helper'; -import { Permissions } from '~/app/shared/models/permissions'; -import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; -import { FeatureTogglesService } from '~/app/shared/services/feature-toggles.service'; -import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service'; -import { SharedModule } from '~/app/shared/shared.module'; -import { configureTestBed } from '~/testing/unit-test-helper'; -import { HealthPieComponent } from '../health-pie/health-pie.component'; -import { MdsDashboardSummaryPipe } from '../mds-dashboard-summary.pipe'; -import { MgrDashboardSummaryPipe } from '../mgr-dashboard-summary.pipe'; -import { MonSummaryPipe } from '../mon-summary.pipe'; -import { osdDashboardSummaryPipe } from '../osd-dashboard-summary.pipe'; -import { HealthComponent } from './health.component'; - -describe('HealthComponent', () => { - let component: HealthComponent; - let fixture: ComponentFixture; - let getHealthSpy: jasmine.Spy; - const healthPayload: Record = { - health: { status: 'HEALTH_OK' }, - mon_status: { monmap: { mons: [] }, quorum: [] }, - osd_map: { osds: [] }, - mgr_map: { standbys: [] }, - hosts: 0, - rgw: 0, - fs_map: { filesystems: [], standbys: [] }, - iscsi_daemons: 0, - client_perf: {}, - scrub_status: 'Inactive', - pools: [], - df: { stats: {} }, - pg_info: { object_stats: { num_objects: 0 } } - }; - const fakeAuthStorageService = { - getPermissions: () => { - return new Permissions({ log: ['read'] }); - } - }; - let fakeFeatureTogglesService: jasmine.Spy; - - configureTestBed({ - imports: [SharedModule, HttpClientTestingModule], - declarations: [ - HealthComponent, - HealthPieComponent, - MonSummaryPipe, - osdDashboardSummaryPipe, - MdsDashboardSummaryPipe, - MgrDashboardSummaryPipe - ], - schemas: [NO_ERRORS_SCHEMA], - providers: [ - { provide: AuthStorageService, useValue: fakeAuthStorageService }, - PgCategoryService, - RefreshIntervalService, - CssHelper - ] - }); - - beforeEach(() => { - fakeFeatureTogglesService = spyOn(TestBed.inject(FeatureTogglesService), 'get').and.returnValue( - of({ - rbd: true, - mirroring: true, - iscsi: true, - cephfs: true, - rgw: true - }) - ); - fixture = TestBed.createComponent(HealthComponent); - component = fixture.componentInstance; - getHealthSpy = spyOn(TestBed.inject(HealthService), 'getMinimalHealth'); - getHealthSpy.and.returnValue(of(healthPayload)); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('should render all info groups and all info cards', () => { - fixture.detectChanges(); - - const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group'); - expect(infoGroups.length).toBe(3); - - const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card'); - expect(infoCards.length).toBe(17); - }); - - describe('features disabled', () => { - beforeEach(() => { - fakeFeatureTogglesService.and.returnValue( - of({ - rbd: false, - mirroring: false, - iscsi: false, - cephfs: false, - rgw: false - }) - ); - fixture = TestBed.createComponent(HealthComponent); - component = fixture.componentInstance; - }); - - it('should not render cards related to disabled features', () => { - fixture.detectChanges(); - - const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group'); - expect(infoGroups.length).toBe(3); - - const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card'); - expect(infoCards.length).toBe(14); - }); - }); - - it('should render all except "Status" group and cards', () => { - const payload = _.cloneDeep(healthPayload); - payload.health.status = ''; - payload.mon_status = null; - payload.osd_map = null; - payload.mgr_map = null; - payload.hosts = null; - payload.rgw = null; - payload.fs_map = null; - payload.iscsi_daemons = null; - - getHealthSpy.and.returnValue(of(payload)); - fixture.detectChanges(); - - const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group'); - expect(infoGroups.length).toBe(2); - - const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card'); - expect(infoCards.length).toBe(9); - }); - - it('should render all except "Performance" group and cards', () => { - const payload = _.cloneDeep(healthPayload); - payload.scrub_status = ''; - payload.client_perf = null; - - getHealthSpy.and.returnValue(of(payload)); - fixture.detectChanges(); - - const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group'); - expect(infoGroups.length).toBe(2); - - const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card'); - expect(infoCards.length).toBe(13); - }); - - it('should render all except "Capacity" group and cards', () => { - const payload = _.cloneDeep(healthPayload); - payload.pools = null; - payload.df = null; - payload.pg_info = null; - - getHealthSpy.and.returnValue(of(payload)); - fixture.detectChanges(); - - const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group'); - expect(infoGroups.length).toBe(2); - - const infoCards = fixture.debugElement.nativeElement.querySelectorAll('cd-info-card'); - expect(infoCards.length).toBe(12); - }); - - it('should render all groups and 1 card per group', () => { - const payload: Record = { hosts: 0, scrub_status: 'Inactive', pools: [] }; - - getHealthSpy.and.returnValue(of(payload)); - fixture.detectChanges(); - - const infoGroups = fixture.debugElement.nativeElement.querySelectorAll('cd-info-group'); - expect(infoGroups.length).toBe(3); - - _.each(infoGroups, (infoGroup) => { - expect(infoGroup.querySelectorAll('cd-info-card').length).toBe(1); - }); - }); - - it('should render "Cluster Status" card text that is not clickable', () => { - fixture.detectChanges(); - - const clusterStatusCard = fixture.debugElement.query( - By.css('cd-info-card[cardTitle="Cluster Status"]') - ); - const clickableContent = clusterStatusCard.query(By.css('.info-card-content-clickable')); - expect(clickableContent).toBeNull(); - expect(clusterStatusCard.nativeElement.textContent).toEqual(' OK '); - }); - - it('should render "Cluster Status" card text that is clickable (popover)', () => { - const payload = _.cloneDeep(healthPayload); - payload.health['status'] = 'HEALTH_WARN'; - payload.health['checks'] = [ - { severity: 'HEALTH_WARN', type: 'WRN', summary: { message: 'fake warning' } } - ]; - - getHealthSpy.and.returnValue(of(payload)); - fixture.detectChanges(); - - expect(component.permissions.log.read).toBeTruthy(); - - const clusterStatusCard = fixture.debugElement.query( - By.css('cd-info-card[cardTitle="Cluster Status"]') - ); - const clickableContent = clusterStatusCard.query(By.css('.info-card-content-clickable')); - expect(clickableContent.nativeElement.textContent).toEqual(' WARNING '); - }); - - it('event binding "prepareReadWriteRatio" is called', () => { - const prepareReadWriteRatio = spyOn(component, 'prepareReadWriteRatio').and.callThrough(); - - const payload = _.cloneDeep(healthPayload); - payload.client_perf['read_op_per_sec'] = 1; - payload.client_perf['write_op_per_sec'] = 3; - getHealthSpy.and.returnValue(of(payload)); - fixture.detectChanges(); - - expect(prepareReadWriteRatio).toHaveBeenCalled(); - expect(prepareReadWriteRatio.calls.mostRecent().args[0].dataset[0].data).toEqual([25, 75]); - }); - - it('event binding "prepareRawUsage" is called', () => { - const prepareRawUsage = spyOn(component, 'prepareRawUsage'); - - fixture.detectChanges(); - - expect(prepareRawUsage).toHaveBeenCalled(); - }); - - it('event binding "preparePgStatus" is called', () => { - const preparePgStatus = spyOn(component, 'preparePgStatus'); - - fixture.detectChanges(); - - expect(preparePgStatus).toHaveBeenCalled(); - }); - - it('event binding "prepareObjects" is called', () => { - const prepareObjects = spyOn(component, 'prepareObjects'); - - fixture.detectChanges(); - - expect(prepareObjects).toHaveBeenCalled(); - }); - - describe('preparePgStatus', () => { - const expectedChart = (data: number[], label: string = null) => ({ - labels: [ - `Clean: ${component['dimless'].transform(data[0])}`, - `Working: ${component['dimless'].transform(data[1])}`, - `Warning: ${component['dimless'].transform(data[2])}`, - `Unknown: ${component['dimless'].transform(data[3])}` - ], - options: {}, - dataset: [ - { - data: data.map((i) => - component['calcPercentage']( - i, - data.reduce((j, k) => j + k) - ) - ), - label: label - } - ] - }); - - it('gets no data', () => { - const chart = { dataset: [{}], options: {} }; - component.preparePgStatus(chart, { - pg_info: {} - }); - expect(chart).toEqual(expectedChart([0, 0, 0, 0], '0\nPGs')); - }); - - it('gets data from all categories', () => { - const chart = { dataset: [{}], options: {} }; - component.preparePgStatus(chart, { - pg_info: { - statuses: { - 'clean+active+scrubbing+nonMappedState': 4, - 'clean+active+scrubbing': 2, - 'clean+active': 1, - 'clean+active+scrubbing+down': 3 - } - } - }); - expect(chart).toEqual(expectedChart([1, 2, 3, 4], '10\nPGs')); - }); - }); - - describe('isClientReadWriteChartShowable', () => { - beforeEach(() => { - component.healthData = healthPayload; - }); - - it('returns false', () => { - component.healthData['client_perf'] = {}; - - expect(component.isClientReadWriteChartShowable()).toBeFalsy(); - }); - - it('returns false', () => { - component.healthData['client_perf'] = { read_op_per_sec: undefined, write_op_per_sec: 0 }; - - expect(component.isClientReadWriteChartShowable()).toBeFalsy(); - }); - - it('returns true', () => { - component.healthData['client_perf'] = { read_op_per_sec: 1, write_op_per_sec: undefined }; - - expect(component.isClientReadWriteChartShowable()).toBeTruthy(); - }); - - it('returns true', () => { - component.healthData['client_perf'] = { read_op_per_sec: 2, write_op_per_sec: 3 }; - - expect(component.isClientReadWriteChartShowable()).toBeTruthy(); - }); - }); - - describe('calcPercentage', () => { - it('returns correct value', () => { - expect(component['calcPercentage'](1, undefined)).toEqual(0); - expect(component['calcPercentage'](1, null)).toEqual(0); - expect(component['calcPercentage'](1, 0)).toEqual(0); - expect(component['calcPercentage'](undefined, 1)).toEqual(0); - expect(component['calcPercentage'](null, 1)).toEqual(0); - expect(component['calcPercentage'](0, 1)).toEqual(0); - expect(component['calcPercentage'](1, 100000)).toEqual(0.01); - expect(component['calcPercentage'](2.346, 10)).toEqual(23.46); - expect(component['calcPercentage'](2.56, 10)).toEqual(25.6); - }); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts deleted file mode 100644 index fac206be59c5..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts +++ /dev/null @@ -1,281 +0,0 @@ -import { Component, OnDestroy, OnInit } from '@angular/core'; - -import _ from 'lodash'; -import { Subscription } from 'rxjs'; -import { take } from 'rxjs/operators'; - -import { PgCategoryService } from '~/app/ceph/shared/pg-category.service'; -import { HealthService } from '~/app/shared/api/health.service'; -import { OsdService } from '~/app/shared/api/osd.service'; -import { CssHelper } from '~/app/shared/classes/css-helper'; -import { Icons } from '~/app/shared/enum/icons.enum'; -import { OsdSettings } from '~/app/shared/models/osd-settings'; -import { Permissions } from '~/app/shared/models/permissions'; -import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe'; -import { DimlessPipe } from '~/app/shared/pipes/dimless.pipe'; -import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; -import { - FeatureTogglesMap$, - FeatureTogglesService -} from '~/app/shared/services/feature-toggles.service'; -import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service'; - -@Component({ - selector: 'cd-health', - templateUrl: './health.component.html', - styleUrls: ['./health.component.scss'] -}) -export class HealthComponent implements OnInit, OnDestroy { - healthData: any; - osdSettings = new OsdSettings(); - interval = new Subscription(); - permissions: Permissions; - enabledFeature$: FeatureTogglesMap$; - icons = Icons; - color: string; - clientStatsConfig: any = {}; - rawCapacityChartConfig: any = {}; - pgStatusChartConfig = { - options: { - events: [''] - } - }; - - constructor( - private healthService: HealthService, - private osdService: OsdService, - private authStorageService: AuthStorageService, - private pgCategoryService: PgCategoryService, - private featureToggles: FeatureTogglesService, - private refreshIntervalService: RefreshIntervalService, - private dimlessBinary: DimlessBinaryPipe, - private dimless: DimlessPipe, - private cssHelper: CssHelper - ) { - this.permissions = this.authStorageService.getPermissions(); - this.enabledFeature$ = this.featureToggles.get(); - } - - ngOnInit() { - this.clientStatsConfig = { - dataset: [ - { - backgroundColor: [ - this.cssHelper.propertyValue('chart-color-cyan'), - this.cssHelper.propertyValue('chart-color-purple') - ] - } - ] - }; - - this.rawCapacityChartConfig = { - dataset: [ - { - backgroundColor: [ - this.cssHelper.propertyValue('chart-color-blue'), - this.cssHelper.propertyValue('chart-color-gray') - ] - } - ] - }; - this.interval = this.refreshIntervalService.intervalData$.subscribe(() => { - this.getHealth(); - }); - - this.osdService - .getOsdSettings() - .pipe(take(1)) - .subscribe((data: any) => { - this.osdSettings = data; - }); - } - - ngOnDestroy() { - this.interval.unsubscribe(); - } - - getHealth() { - this.healthService.getMinimalHealth().subscribe((data: any) => { - this.healthData = data; - }); - } - - prepareReadWriteRatio(chart: Record) { - const ratioLabels = []; - const ratioData = []; - - const total = - this.healthData.client_perf.write_op_per_sec + this.healthData.client_perf.read_op_per_sec; - - ratioLabels.push( - `${$localize`Reads`}: ${this.dimless.transform( - this.healthData.client_perf.read_op_per_sec - )} ${$localize`/s`}` - ); - ratioData.push(this.calcPercentage(this.healthData.client_perf.read_op_per_sec, total)); - ratioLabels.push( - `${$localize`Writes`}: ${this.dimless.transform( - this.healthData.client_perf.write_op_per_sec - )} ${$localize`/s`}` - ); - ratioData.push(this.calcPercentage(this.healthData.client_perf.write_op_per_sec, total)); - - chart.labels = ratioLabels; - chart.dataset[0].data = ratioData; - chart.dataset[0].label = `${this.dimless.transform(total)}\n${$localize`IOPS`}`; - } - - prepareClientThroughput(chart: Record) { - const ratioLabels = []; - const ratioData = []; - - const total = - this.healthData.client_perf.read_bytes_sec + this.healthData.client_perf.write_bytes_sec; - - ratioLabels.push( - `${$localize`Reads`}: ${this.dimlessBinary.transform( - this.healthData.client_perf.read_bytes_sec - )}${$localize`/s`}` - ); - ratioData.push(this.calcPercentage(this.healthData.client_perf.read_bytes_sec, total)); - ratioLabels.push( - `${$localize`Writes`}: ${this.dimlessBinary.transform( - this.healthData.client_perf.write_bytes_sec - )}${$localize`/s`}` - ); - ratioData.push(this.calcPercentage(this.healthData.client_perf.write_bytes_sec, total)); - - chart.labels = ratioLabels; - chart.dataset[0].data = ratioData; - chart.dataset[0].label = `${this.dimlessBinary - .transform(total) - .replace(' ', '\n')}${$localize`/s`}`; - } - - prepareRawUsage(chart: Record, data: Record) { - const percentAvailable = this.calcPercentage( - data.df.stats.total_bytes - data.df.stats.total_used_raw_bytes, - data.df.stats.total_bytes - ); - const percentUsed = this.calcPercentage( - data.df.stats.total_used_raw_bytes, - data.df.stats.total_bytes - ); - - const nearfullRatio = this.osdSettings.nearfull_ratio; - const fullRatio = this.osdSettings.nearfull_ratio; - - if (nearfullRatio >= 0 && percentUsed / 100 >= nearfullRatio) { - this.color = 'chart-color-red'; - } else if (fullRatio >= 0 && percentUsed / 100 >= fullRatio) { - this.color = 'chart-color-yellow'; - } else { - this.color = 'chart-color-blue'; - } - this.rawCapacityChartConfig.dataset[0].backgroundColor[0] = this.cssHelper.propertyValue( - this.color - ); - - chart.dataset[0].data = [percentUsed, percentAvailable]; - - chart.labels = [ - `${$localize`Used`}: ${this.dimlessBinary.transform(data.df.stats.total_used_raw_bytes)}`, - `${$localize`Avail.`}: ${this.dimlessBinary.transform( - data.df.stats.total_bytes - data.df.stats.total_used_raw_bytes - )}` - ]; - - chart.dataset[0].label = `${percentUsed}%\nof ${this.dimlessBinary.transform( - data.df.stats.total_bytes - )}`; - } - - preparePgStatus(chart: Record, data: Record) { - const categoryPgAmount: Record = {}; - let totalPgs = 0; - - _.forEach(data.pg_info.statuses, (pgAmount, pgStatesText) => { - const categoryType = this.pgCategoryService.getTypeByStates(pgStatesText); - - if (_.isUndefined(categoryPgAmount[categoryType])) { - categoryPgAmount[categoryType] = 0; - } - categoryPgAmount[categoryType] += pgAmount; - totalPgs += pgAmount; - }); - - for (const categoryType of this.pgCategoryService.getAllTypes()) { - if (_.isUndefined(categoryPgAmount[categoryType])) { - categoryPgAmount[categoryType] = 0; - } - } - - chart.dataset[0].data = this.pgCategoryService - .getAllTypes() - .map((categoryType) => this.calcPercentage(categoryPgAmount[categoryType], totalPgs)); - - chart.labels = [ - `${$localize`Clean`}: ${this.dimless.transform(categoryPgAmount['clean'])}`, - `${$localize`Working`}: ${this.dimless.transform(categoryPgAmount['working'])}`, - `${$localize`Warning`}: ${this.dimless.transform(categoryPgAmount['warning'])}`, - `${$localize`Unknown`}: ${this.dimless.transform(categoryPgAmount['unknown'])}` - ]; - - chart.dataset[0].label = `${totalPgs}\n${$localize`PGs`}`; - } - - prepareObjects(chart: Record, data: Record) { - const objectCopies = data.pg_info.object_stats.num_object_copies; - const healthy = - objectCopies - - data.pg_info.object_stats.num_objects_misplaced - - data.pg_info.object_stats.num_objects_degraded - - data.pg_info.object_stats.num_objects_unfound; - const healthyPercentage = this.calcPercentage(healthy, objectCopies); - const misplacedPercentage = this.calcPercentage( - data.pg_info.object_stats.num_objects_misplaced, - objectCopies - ); - const degradedPercentage = this.calcPercentage( - data.pg_info.object_stats.num_objects_degraded, - objectCopies - ); - const unfoundPercentage = this.calcPercentage( - data.pg_info.object_stats.num_objects_unfound, - objectCopies - ); - - chart.labels = [ - `${$localize`Healthy`}: ${healthyPercentage}%`, - `${$localize`Misplaced`}: ${misplacedPercentage}%`, - `${$localize`Degraded`}: ${degradedPercentage}%`, - `${$localize`Unfound`}: ${unfoundPercentage}%` - ]; - - chart.dataset[0].data = [ - healthyPercentage, - misplacedPercentage, - degradedPercentage, - unfoundPercentage - ]; - - chart.dataset[0].label = `${this.dimless.transform( - data.pg_info.object_stats.num_objects - )}\n${$localize`objects`}`; - } - - isClientReadWriteChartShowable() { - const readOps = this.healthData.client_perf.read_op_per_sec || 0; - const writeOps = this.healthData.client_perf.write_op_per_sec || 0; - - return readOps + writeOps > 0; - } - - private calcPercentage(dividend: number, divisor: number) { - if (!_.isNumber(dividend) || !_.isNumber(divisor) || divisor === 0) { - return 0; - } - - return Math.ceil((dividend / divisor) * 100 * 100) / 100; - } -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss deleted file mode 100644 index 10e286973e30..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card-popover.scss +++ /dev/null @@ -1,55 +0,0 @@ -@use './src/styles/vendor/variables' as vv; - -.info-card-popover-cluster-status { - max-height: 20vh; - max-width: 23vw; - - .popover-body { - font-size: 1rem; - max-height: 19vh; - max-width: 100%; - overflow: auto; - - li { - span { - font-size: 1.1em; - font-weight: bold; - } - - span.health-warn-description { - color: vv.$health-color-warning-800 !important; - } - } - } -} - -@media (max-width: vv.$screen-lg-max) { - .info-card-popover-cluster-status { - max-width: 31vw; - } -} - -@media (max-width: vv.$screen-md-max) { - .info-card-popover-cluster-status { - max-width: 46vw; - } -} - -@media (max-width: vv.$screen-sm-max) { - .info-card-popover-cluster-status { - max-width: 83vw; - } -} - -.info-card-content-clickable { - border: 1px solid vv.$gray-200; - border-radius: 3px; - cursor: pointer; - font-size: 1.25em; - padding: 7px; -} - -.info-card-content-clickable:hover { - background-color: vv.$gray-200; - border-color: vv.$gray-400; -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html deleted file mode 100644 index ef032850271b..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.html +++ /dev/null @@ -1,18 +0,0 @@ -
-
-

- {{ cardTitle }} - - - {{ cardTitle }} - -

- -
- -
-
-
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss deleted file mode 100644 index c84eff53ae21..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.scss +++ /dev/null @@ -1,45 +0,0 @@ -@use './src/styles/vendor/variables' as vv; -@use './src/styles/defaults/mixins'; - -$card-font-min-width: 320px; -$card-font-max-width: 2048px; -$card-font-min-size: 12px; -$card-font-max-size: 21px; - -.card { - @include mixins.fluid-font-size( - $card-font-min-width, - $card-font-max-width, - $card-font-min-size, - $card-font-max-size - ); - - border: 0.5px solid vv.$gray-300; - border-radius: 3px; - height: 100%; - - .card-body { - padding-top: 40px !important; - - .card-title { - left: -0.6rem; - position: absolute; - top: -0.3rem; - } - - .card-title > a { - color: vv.$primary; - } - } -} - -.no-center { - left: unset; - position: unset; - top: unset; - transform: unset; -} - -.content-highlight { - font-weight: bold; -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts deleted file mode 100644 index bde9a9a00b23..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { RouterTestingModule } from '@angular/router/testing'; - -import { configureTestBed } from '~/testing/unit-test-helper'; -import { InfoCardComponent } from './info-card.component'; - -describe('InfoCardComponent', () => { - let component: InfoCardComponent; - let fixture: ComponentFixture; - - configureTestBed({ - imports: [RouterTestingModule], - declarations: [InfoCardComponent] - }); - - beforeEach(() => { - fixture = TestBed.createComponent(InfoCardComponent); - component = fixture.componentInstance; - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('Setting cardTitle makes title visible', () => { - const cardTitle = 'Card Title'; - component.cardTitle = cardTitle; - fixture.detectChanges(); - const titleDiv = fixture.debugElement.nativeElement.querySelector('.card-title'); - - expect(titleDiv.textContent).toContain(cardTitle); - }); - - it('Setting link makes anchor visible', () => { - const cardTitle = 'Card Title'; - const link = '/dashboard'; - component.cardTitle = cardTitle; - component.link = link; - fixture.detectChanges(); - const anchor = fixture.debugElement.nativeElement - .querySelector('.card-title') - .querySelector('a'); - - expect(anchor.textContent).toContain(cardTitle); - expect(anchor.href).toBe(`http://localhost${link}`); - }); - - it('Setting cardClass makes class set', () => { - const cardClass = 'my-css-card-class'; - component.cardClass = cardClass; - fixture.detectChanges(); - const card = fixture.debugElement.nativeElement.querySelector(`.card.${cardClass}`); - - expect(card).toBeTruthy(); - }); - - it('Setting contentClass makes class set', () => { - const contentClass = 'my-css-content-class'; - component.contentClass = contentClass; - fixture.detectChanges(); - const card = fixture.debugElement.nativeElement.querySelector(`.card-body .${contentClass}`); - - expect(card).toBeTruthy(); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts deleted file mode 100644 index fdcbe2ecea51..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-card/info-card.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, Input } from '@angular/core'; - -@Component({ - selector: 'cd-info-card', - templateUrl: './info-card.component.html', - styleUrls: ['./info-card.component.scss'] -}) -export class InfoCardComponent { - @Input() - cardTitle: string; - @Input() - link: string; - @Input() - cardClass = ''; - @Input() - contentClass: string; -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html deleted file mode 100644 index d78350b143c7..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.html +++ /dev/null @@ -1,17 +0,0 @@ -
-
- {{ groupTitle }} - -
For an overview of {{ groupTitle|lowercase }} widgets click - -
-
-
-
- -
- -
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss deleted file mode 100644 index ce2057e6a36c..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.scss +++ /dev/null @@ -1,14 +0,0 @@ -@use './src/styles/vendor/variables' as vv; - -.info-group-title { - font-size: 1.75rem; - margin: 0 0 0.5vw; -} - -.popover-icon { - color: vv.$primary; -} - -.popover-icon:focus { - box-shadow: none; -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts deleted file mode 100644 index 1ac1cb60b3c2..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; - -import { SharedModule } from '~/app/shared/shared.module'; -import { configureTestBed } from '~/testing/unit-test-helper'; -import { InfoGroupComponent } from './info-group.component'; - -describe('InfoGroupComponent', () => { - let component: InfoGroupComponent; - let fixture: ComponentFixture; - - configureTestBed({ - imports: [NgbPopoverModule, SharedModule, HttpClientTestingModule], - declarations: [InfoGroupComponent] - }); - - beforeEach(() => { - fixture = TestBed.createComponent(InfoGroupComponent); - component = fixture.componentInstance; - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - it('Setting groupTitle makes title visible', () => { - const groupTitle = 'Group Title'; - component.groupTitle = groupTitle; - fixture.detectChanges(); - const titleDiv = fixture.debugElement.nativeElement.querySelector('.info-group-title'); - - expect(titleDiv.textContent).toContain(groupTitle); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts deleted file mode 100644 index 167db9e2fa99..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/info-group/info-group.component.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Component, Input } from '@angular/core'; - -import { Icons } from '~/app/shared/enum/icons.enum'; - -@Component({ - selector: 'cd-info-group', - templateUrl: './info-group.component.html', - styleUrls: ['./info-group.component.scss'] -}) -export class InfoGroupComponent { - icons = Icons; - @Input() - groupTitle: string; -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.spec.ts deleted file mode 100644 index c091a35544b8..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.spec.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { configureTestBed } from '~/testing/unit-test-helper'; -import { MdsDashboardSummaryPipe } from './mds-dashboard-summary.pipe'; - -describe('MdsDashboardSummaryPipe', () => { - let pipe: MdsDashboardSummaryPipe; - - configureTestBed({ - providers: [MdsDashboardSummaryPipe] - }); - - beforeEach(() => { - pipe = TestBed.inject(MdsDashboardSummaryPipe); - }); - - it('create an instance', () => { - expect(pipe).toBeTruthy(); - }); - - it('transforms with 0 active and 2 standy', () => { - const payload = { - standbys: [{ name: 'a' }], - filesystems: [{ mdsmap: { info: [{ state: 'up:standby-replay' }] } }] - }; - const expected = [ - { class: 'popover-info', content: '0 active', titleText: '1 standbyReplay' }, - { class: 'card-text-line-break', content: '', titleText: '' }, - { class: 'popover-info', content: '2 standby', titleText: 'standby daemons: a' } - ]; - - expect(pipe.transform(payload)).toEqual(expected); - }); - - it('transforms with 1 active and 1 standy', () => { - const payload = { - standbys: [{ name: 'b' }], - filesystems: [{ mdsmap: { info: [{ state: 'up:active', name: 'a' }] } }] - }; - const expected = [ - { class: 'popover-info', content: '1 active', titleText: 'active daemon: a' }, - { class: 'card-text-line-break', content: '', titleText: '' }, - { class: 'popover-info', content: '1 standby', titleText: 'standby daemons: b' } - ]; - expect(pipe.transform(payload)).toEqual(expected); - }); - - it('transforms with 0 filesystems', () => { - const payload: Record = { - standbys: [0], - filesystems: [] - }; - const expected = [{ class: 'popover-info', content: 'no filesystems', titleText: '' }]; - - expect(pipe.transform(payload)).toEqual(expected); - }); - - it('transforms without filesystem', () => { - const payload = { standbys: [{ name: 'a' }] }; - const expected = [ - { class: 'popover-info', content: '1 up', titleText: '' }, - { class: 'card-text-line-break', content: '', titleText: '' }, - { class: 'popover-info', content: 'no filesystems', titleText: 'standby daemons: a' } - ]; - - expect(pipe.transform(payload)).toEqual(expected); - }); - - it('transforms without value', () => { - expect(pipe.transform(undefined)).toBe(''); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.ts deleted file mode 100644 index 2b4a899eebd0..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mds-dashboard-summary.pipe.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; - -import _ from 'lodash'; - -@Pipe({ - name: 'mdsDashboardSummary' -}) -export class MdsDashboardSummaryPipe implements PipeTransform { - transform(value: any): any { - if (!value) { - return ''; - } - - let contentLine1 = ''; - let contentLine2 = ''; - let standbys = 0; - let active = 0; - let standbyReplay = 0; - _.each(value.standbys, () => { - standbys += 1; - }); - - if (value.standbys && !value.filesystems) { - contentLine1 = `${standbys} ${$localize`up`}`; - contentLine2 = $localize`no filesystems`; - } else if (value.filesystems.length === 0) { - contentLine1 = $localize`no filesystems`; - } else { - _.each(value.filesystems, (fs) => { - _.each(fs.mdsmap.info, (mds) => { - if (mds.state === 'up:standby-replay') { - standbyReplay += 1; - } else { - active += 1; - } - }); - }); - - contentLine1 = `${active} ${$localize`active`}`; - contentLine2 = `${standbys + standbyReplay} ${$localize`standby`}`; - } - const standbyHoverText = value.standbys.map((s: any): string => s.name).join(', '); - const standbyTitleText = !standbyHoverText - ? '' - : `${$localize`standby daemons`}: ${standbyHoverText}`; - const fsLength = value.filesystems ? value.filesystems.length : 0; - const infoObject = fsLength > 0 ? value.filesystems[0].mdsmap.info : {}; - const activeHoverText = Object.values(infoObject) - .map((info: any): string => info.name) - .join(', '); - let activeTitleText = !activeHoverText ? '' : `${$localize`active daemon`}: ${activeHoverText}`; - // There is always one standbyreplay to replace active daemon, if active one is down - if (!active && fsLength > 0) { - activeTitleText = `${standbyReplay} ${$localize`standbyReplay`}`; - } - const mgrSummary = [ - { - content: contentLine1, - class: 'popover-info', - titleText: activeTitleText - } - ]; - if (contentLine2) { - mgrSummary.push({ - content: '', - class: 'card-text-line-break', - titleText: '' - }); - mgrSummary.push({ - content: contentLine2, - class: 'popover-info', - titleText: standbyTitleText - }); - } - - return mgrSummary; - } -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.spec.ts deleted file mode 100644 index 3bd9242e3c30..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.spec.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { configureTestBed } from '~/testing/unit-test-helper'; -import { MgrDashboardSummaryPipe } from './mgr-dashboard-summary.pipe'; - -describe('MgrDashboardSummaryPipe', () => { - let pipe: MgrDashboardSummaryPipe; - - configureTestBed({ - providers: [MgrDashboardSummaryPipe] - }); - - beforeEach(() => { - pipe = TestBed.inject(MgrDashboardSummaryPipe); - }); - - it('create an instance', () => { - expect(pipe).toBeTruthy(); - }); - - it('transforms without value', () => { - expect(pipe.transform(undefined)).toBe(''); - }); - - it('transforms with active_name undefined', () => { - const payload: Record = { - active_name: undefined, - standbys: [] - }; - const expected = [ - { class: 'popover-info', content: 'n/a active', titleText: '' }, - { class: 'card-text-line-break', content: '', titleText: '' }, - { class: 'popover-info', content: '0 standby', titleText: '' } - ]; - - expect(pipe.transform(payload)).toEqual(expected); - }); - - it('transforms with 1 active and 2 standbys', () => { - const payload = { - active_name: 'x', - standbys: [{ name: 'y' }, { name: 'z' }] - }; - const expected = [ - { class: 'popover-info', content: '1 active', titleText: 'active daemon: x' }, - { class: 'card-text-line-break', content: '', titleText: '' }, - { class: 'popover-info', content: '2 standby', titleText: 'standby daemons: y, z' } - ]; - - expect(pipe.transform(payload)).toEqual(expected); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.ts deleted file mode 100644 index b82e5d852fc2..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mgr-dashboard-summary.pipe.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; - -import _ from 'lodash'; - -@Pipe({ - name: 'mgrDashboardSummary' -}) -export class MgrDashboardSummaryPipe implements PipeTransform { - transform(value: any): any { - if (!value) { - return ''; - } - - let activeCount = $localize`n/a`; - const activeTitleText = _.isUndefined(value.active_name) - ? '' - : `${$localize`active daemon`}: ${value.active_name}`; - // There is always one standbyreplay to replace active daemon, if active one is down - if (activeTitleText.length > 0) { - activeCount = '1'; - } - const standbyHoverText = value.standbys.map((s: any): string => s.name).join(', '); - const standbyTitleText = !standbyHoverText - ? '' - : `${$localize`standby daemons`}: ${standbyHoverText}`; - const standbyCount = value.standbys.length; - const mgrSummary = [ - { - content: `${activeCount} ${$localize`active`}`, - class: 'popover-info', - titleText: activeTitleText - } - ]; - - mgrSummary.push({ - content: '', - class: 'card-text-line-break', - titleText: '' - }); - mgrSummary.push({ - content: `${standbyCount} ${$localize`standby`}`, - class: 'popover-info', - titleText: standbyTitleText - }); - - return mgrSummary; - } -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts deleted file mode 100644 index b8a083a325c7..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { configureTestBed } from '~/testing/unit-test-helper'; -import { MonSummaryPipe } from './mon-summary.pipe'; - -describe('MonSummaryPipe', () => { - let pipe: MonSummaryPipe; - - configureTestBed({ - providers: [MonSummaryPipe] - }); - - beforeEach(() => { - pipe = TestBed.inject(MonSummaryPipe); - }); - - it('create an instance', () => { - expect(pipe).toBeTruthy(); - }); - - it('transforms without value', () => { - expect(pipe.transform(undefined)).toBe(''); - }); - - it('transforms with 3 mons in quorum', () => { - const value = { - monmap: { mons: [0, 1, 2] }, - quorum: [0, 1, 2] - }; - expect(pipe.transform(value)).toBe('3 (quorum 0, 1, 2)'); - }); - - it('transforms with 2/3 mons in quorum', () => { - const value = { - monmap: { mons: [0, 1, 2] }, - quorum: [0, 1] - }; - expect(pipe.transform(value)).toBe('3 (quorum 0, 1)'); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts deleted file mode 100644 index 399045d5de32..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/mon-summary.pipe.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; - -@Pipe({ - name: 'monSummary' -}) -export class MonSummaryPipe implements PipeTransform { - transform(value: any): any { - if (!value) { - return ''; - } - - const result = $localize`${value.monmap.mons.length.toString()} (quorum \ -${value.quorum.join(', ')})`; - - return result; - } -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.spec.ts deleted file mode 100644 index f5af99b44686..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.spec.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { configureTestBed } from '~/testing/unit-test-helper'; -import { osdDashboardSummaryPipe } from './osd-dashboard-summary.pipe'; - -describe('osdDashboardSummaryPipe', () => { - let pipe: osdDashboardSummaryPipe; - - configureTestBed({ - providers: [osdDashboardSummaryPipe] - }); - - beforeEach(() => { - pipe = TestBed.inject(osdDashboardSummaryPipe); - }); - - it('create an instance', () => { - expect(pipe).toBeTruthy(); - }); - - it('transforms without value', () => { - expect(pipe.transform(undefined)).toBe(''); - }); - - it('transforms having 3 osd with 3 up, 3 in, 0 down, 0 out', () => { - const value = { - osds: [ - { up: 1, in: 1, state: ['up', 'exists'] }, - { up: 1, in: 1, state: ['up', 'exists'] }, - { up: 1, in: 1, state: ['up', 'exists'] } - ] - }; - expect(pipe.transform(value)).toEqual([ - { - content: '3 total', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '3 up, 3 in', - class: '' - } - ]); - }); - - it('transforms having 3 osd with 2 up, 1 in, 1 down, 2 out', () => { - const value = { - osds: [ - { up: 1, in: 1, state: ['up', 'exists'] }, - { up: 1, in: 0, state: ['up', 'exists'] }, - { up: 0, in: 0, state: ['exists'] } - ] - }; - expect(pipe.transform(value)).toEqual([ - { - content: '3 total', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '2 up, 1 in', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '1 down, 2 out', - class: 'card-text-error' - } - ]); - }); - - it('transforms having 3 osd with 2 up, 3 in, 1 full, 1 nearfull, 1 down, 0 out', () => { - const value = { - osds: [ - { up: 1, in: 1, state: ['up', 'nearfull'] }, - { up: 1, in: 1, state: ['up', 'exists'] }, - { up: 0, in: 1, state: ['full'] } - ] - }; - expect(pipe.transform(value)).toEqual([ - { - content: '3 total', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '2 up, 3 in', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '1 down', - class: 'card-text-error' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '1 near full', - class: 'card-text-error' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '1 full', - class: 'card-text-error' - } - ]); - }); - - it('transforms having 3 osd with 3 up, 2 in, 0 down, 1 out', () => { - const value = { - osds: [ - { up: 1, in: 1, state: ['up', 'exists'] }, - { up: 1, in: 1, state: ['up', 'exists'] }, - { up: 1, in: 0, state: ['up', 'exists'] } - ] - }; - expect(pipe.transform(value)).toEqual([ - { - content: '3 total', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '3 up, 2 in', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '1 out', - class: 'card-text-error' - } - ]); - }); - - it('transforms having 4 osd with 3 up, 2 in, 1 down, another 2 out', () => { - const value = { - osds: [ - { up: 1, in: 1, state: ['up', 'exists'] }, - { up: 1, in: 0, state: ['up', 'exists'] }, - { up: 1, in: 0, state: ['up', 'exists'] }, - { up: 0, in: 1, state: ['exists'] } - ] - }; - expect(pipe.transform(value)).toEqual([ - { - content: '4 total', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '3 up, 2 in', - class: '' - }, - { - content: '', - class: 'card-text-line-break' - }, - { - content: '1 down, 2 out', - class: 'card-text-error' - } - ]); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.ts deleted file mode 100644 index a3e292f073e3..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/osd-dashboard-summary.pipe.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Pipe, PipeTransform } from '@angular/core'; - -import _ from 'lodash'; - -@Pipe({ - name: 'osdDashboardSummary' -}) -export class osdDashboardSummaryPipe implements PipeTransform { - transform(value: any): any { - if (!value) { - return ''; - } - - let inCount = 0; - let upCount = 0; - let nearFullCount = 0; - let fullCount = 0; - _.each(value.osds, (osd) => { - if (osd.in) { - inCount++; - } - if (osd.up) { - upCount++; - } - if (osd.state.includes('nearfull')) { - nearFullCount++; - } - if (osd.state.includes('full')) { - fullCount++; - } - }); - - const osdSummary = [ - { - content: `${value.osds.length} ${$localize`total`}`, - class: '' - } - ]; - osdSummary.push({ - content: '', - class: 'card-text-line-break' - }); - osdSummary.push({ - content: `${upCount} ${$localize`up`}, ${inCount} ${$localize`in`}`, - class: '' - }); - - const downCount = value.osds.length - upCount; - const outCount = value.osds.length - inCount; - if (downCount > 0 || outCount > 0) { - osdSummary.push({ - content: '', - class: 'card-text-line-break' - }); - - const downText = downCount > 0 ? `${downCount} ${$localize`down`}` : ''; - const separator = downCount > 0 && outCount > 0 ? ', ' : ''; - const outText = outCount > 0 ? `${outCount} ${$localize`out`}` : ''; - osdSummary.push({ - content: `${downText}${separator}${outText}`, - class: 'card-text-error' - }); - } - - if (nearFullCount > 0) { - osdSummary.push( - { - content: '', - class: 'card-text-line-break' - }, - { - content: `${nearFullCount} ${$localize`near full`}`, - class: 'card-text-error' - }, - { - content: '', - class: 'card-text-line-break' - } - ); - } - - if (fullCount > 0) { - osdSummary.push({ - content: `${fullCount} ${$localize`full`}`, - class: 'card-text-error' - }); - } - - return osdSummary; - } -} 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 2859ed0f0c60..459ee01f2d31 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 @@ -69,7 +69,6 @@ import { ModalComponent } from './modal/modal.component'; import { NotificationsSidebarComponent } from './notifications-sidebar/notifications-sidebar.component'; import { OrchestratorDocPanelComponent } from './orchestrator-doc-panel/orchestrator-doc-panel.component'; import { PwdExpirationNotificationComponent } from './pwd-expiration-notification/pwd-expiration-notification.component'; -import { RefreshSelectorComponent } from './refresh-selector/refresh-selector.component'; import { SelectBadgesComponent } from './select-badges/select-badges.component'; import { SelectComponent } from './select/select.component'; import { SparklineComponent } from './sparkline/sparkline.component'; @@ -159,7 +158,6 @@ import CloseIcon from '@carbon/icons/es/close/16'; GrafanaComponent, SelectComponent, BackButtonComponent, - RefreshSelectorComponent, ConfigOptionComponent, AlertPanelComponent, FormModalComponent, @@ -204,7 +202,6 @@ import CloseIcon from '@carbon/icons/es/close/16'; LanguageSelectorComponent, GrafanaComponent, SelectComponent, - RefreshSelectorComponent, ConfigOptionComponent, AlertPanelComponent, PwdExpirationNotificationComponent, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html deleted file mode 100644 index 08f00e2a16f7..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.html +++ /dev/null @@ -1,19 +0,0 @@ -
-
-
-
- - -
-
-
-
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.scss deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts deleted file mode 100644 index cb98cadd7a3b..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule } from '@angular/forms'; - -import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service'; -import { configureTestBed } from '~/testing/unit-test-helper'; -import { RefreshSelectorComponent } from './refresh-selector.component'; - -describe('RefreshSelectorComponent', () => { - let component: RefreshSelectorComponent; - let fixture: ComponentFixture; - - configureTestBed({ - imports: [FormsModule], - declarations: [RefreshSelectorComponent], - providers: [RefreshIntervalService] - }); - - beforeEach(() => { - fixture = TestBed.createComponent(RefreshSelectorComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts deleted file mode 100644 index 080890e2693b..000000000000 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/refresh-selector/refresh-selector.component.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service'; - -@Component({ - selector: 'cd-refresh-selector', - templateUrl: './refresh-selector.component.html', - styleUrls: ['./refresh-selector.component.scss'] -}) -export class RefreshSelectorComponent implements OnInit { - selectedInterval: number; - intervalList: { [key: string]: number } = { - '5 s': 5000, - '10 s': 10000, - '15 s': 15000, - '30 s': 30000, - '1 min': 60000, - '3 min': 180000, - '5 min': 300000 - }; - intervalKeys = Object.keys(this.intervalList); - - constructor(private refreshIntervalService: RefreshIntervalService) {} - - ngOnInit() { - this.selectedInterval = this.refreshIntervalService.getRefreshInterval() || 5000; - } - - changeRefreshInterval(interval: number) { - this.refreshIntervalService.setRefreshInterval(interval); - } -} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts index 03577681e1a7..bb7f2a0d6145 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts @@ -12,7 +12,6 @@ export class FeatureTogglesMap { cephfs = true; rgw = true; nfs = true; - dashboardV3 = true; } export type Features = keyof FeatureTogglesMap; export type FeatureTogglesMap$ = Observable; diff --git a/src/pybind/mgr/dashboard/frontend/src/styles.scss b/src/pybind/mgr/dashboard/frontend/src/styles.scss index 4066af126ce5..ce69a405f9bb 100644 --- a/src/pybind/mgr/dashboard/frontend/src/styles.scss +++ b/src/pybind/mgr/dashboard/frontend/src/styles.scss @@ -25,7 +25,6 @@ $grid-breakpoints: ( @import 'bootstrap/scss/bootstrap'; @import 'fork-awesome/scss/fork-awesome'; -@import 'app/ceph/dashboard/info-card/info-card-popover.scss'; @import 'app/ceph/rgw/rgw-overview-dashboard/rgw-overview-card-popover.scss'; @import './src/styles/bootstrap-extends'; @import './src/styles/ceph-custom/basics'; diff --git a/src/pybind/mgr/dashboard/openapi.yaml b/src/pybind/mgr/dashboard/openapi.yaml index 7915cbaebf7e..2b3f51067ac8 100755 --- a/src/pybind/mgr/dashboard/openapi.yaml +++ b/src/pybind/mgr/dashboard/openapi.yaml @@ -4631,9 +4631,6 @@ paths: cephfs: description: '' type: boolean - dashboard: - description: '' - type: boolean iscsi: description: '' type: boolean @@ -4656,7 +4653,6 @@ paths: - cephfs - rgw - nfs - - dashboard type: object description: OK '400': diff --git a/src/pybind/mgr/dashboard/plugins/feature_toggles.py b/src/pybind/mgr/dashboard/plugins/feature_toggles.py index 63b1d762c341..8b6f7180dfc2 100644 --- a/src/pybind/mgr/dashboard/plugins/feature_toggles.py +++ b/src/pybind/mgr/dashboard/plugins/feature_toggles.py @@ -26,7 +26,6 @@ class Features(Enum): CEPHFS = 'cephfs' RGW = 'rgw' NFS = 'nfs' - DASHBOARD = 'dashboard' # if we want to add any custom warning message when enabling a feature # we can add it here as key-value pair in warn_msg. @@ -153,7 +152,6 @@ class FeatureToggles(I.CanMgr, I.Setupable, I.HasOptions, "cephfs": (bool, ''), "rgw": (bool, ''), "nfs": (bool, ''), - "dashboard": (bool, '') } @APIRouter('/feature_toggles') -- 2.47.3