]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
mgr/dashboard: Add new landing page component
authorAfreen Misbah <afreen@ibm.com>
Tue, 13 Jan 2026 17:26:34 +0000 (22:56 +0530)
committerAfreen Misbah <afreen@ibm.com>
Sat, 31 Jan 2026 14:49:46 +0000 (20:19 +0530)
Fixes https://tracker.ceph.com/issues/74409

- flagged by DASHBOARD fetaure flag
- added tests
- added layout for overview page
- dropped using get API which is getting polled freqently for perf

Signed-off-by: Afreen Misbah <afreen@ibm.com>
(cherry picked from commit 9a07fbf6e2848025124458faee6db953f6d91a2b)

 Conflicts:
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/services/feature-toggles.service.ts

18 files changed:
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/10501135011127341749 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/12707214466441736553 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/13106400625475788256 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/13685585831439463788 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/1758954290910463637 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/2801012194694874285 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/4379954223956111510 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/5698680818973360491 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/6554461255961944329 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/7234210859985966681 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/741499322021383751 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/9919571031428218619 [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard/dashboard.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.html [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.scss [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/plugins/feature_toggles.py

diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/10501135011127341749 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/10501135011127341749
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/12707214466441736553 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/12707214466441736553
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/13106400625475788256 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/13106400625475788256
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/13685585831439463788 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/13685585831439463788
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/1758954290910463637 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/1758954290910463637
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/2801012194694874285 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/2801012194694874285
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/4379954223956111510 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/4379954223956111510
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/5698680818973360491 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/5698680818973360491
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/6554461255961944329 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/6554461255961944329
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/7234210859985966681 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/7234210859985966681
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/741499322021383751 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/741499322021383751
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
diff --git a/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/9919571031428218619 b/src/pybind/mgr/dashboard/frontend/.nx/cache/terminalOutputs/9919571031428218619
new file mode 100644 (file)
index 0000000..00c1226
--- /dev/null
@@ -0,0 +1,5 @@
+
+Linting "ceph-dashboard"...
+
+All files pass linting.
+
index 9c20e4438f11c73048e334ed5b7f1a43fc53e41e..d3b4f5e8bb97b836b7a6fb4ee2386fc08a092970 100644 (file)
@@ -1,6 +1,7 @@
 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 { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
 import { FeatureTogglesService } from '~/app/shared/services/feature-toggles.service';
@@ -11,6 +12,7 @@ import { DashboardComponent } from './dashboard.component';
 describe('DashboardComponent', () => {
   let component: DashboardComponent;
   let fixture: ComponentFixture<DashboardComponent>;
+  let featureTogglesService: FeatureTogglesService;
 
   configureTestBed({
     imports: [NgbNavModule, HttpClientTestingModule],
@@ -20,12 +22,70 @@ describe('DashboardComponent', () => {
   });
 
   beforeEach(() => {
+    featureTogglesService = TestBed.inject(FeatureTogglesService);
     fixture = TestBed.createComponent(DashboardComponent);
     component = fixture.componentInstance;
-    fixture.detectChanges();
   });
 
   it('should create', () => {
+    spyOn(featureTogglesService, 'isFeatureEnabled').and.returnValue(true);
+
+    fixture.detectChanges();
     expect(component).toBeTruthy();
   });
+
+  it('should call featureTogglesService.isFeatureEnabled() on initialization', () => {
+    const spy = spyOn(featureTogglesService, 'isFeatureEnabled').and.returnValue(true);
+    fixture.detectChanges();
+    expect(spy).toHaveBeenCalled();
+    expect(spy).toHaveBeenCalledWith('dashboard');
+  });
+
+  it('should set useDeprecated based on feature toggle', () => {
+    spyOn(featureTogglesService, 'isFeatureEnabled').and.returnValue(true);
+    fixture.detectChanges();
+    expect(component.useDeprecated).toBe(true);
+  });
+
+  describe('when dashboard feature is enabled (new dashboard)', () => {
+    beforeEach(() => {
+      spyOn(featureTogglesService, 'isFeatureEnabled').and.returnValue(true);
+      fixture.detectChanges();
+    });
+
+    it('should show cd-dashboard-v3 in template when dashboard feature is enabled', () => {
+      const overviewElement = fixture.debugElement.query(By.css('[data-testid="cd-overview"]'));
+      const dashboardV3Element = fixture.debugElement.query(
+        By.css('[data-testid="cd-dashboard-v3"]')
+      );
+
+      expect(overviewElement).toBeNull();
+      expect(dashboardV3Element).toBeTruthy();
+    });
+
+    it('should set useDeprecated to false when feature is enabled', () => {
+      expect(component.useDeprecated).toBe(true);
+    });
+  });
+
+  describe('when dashboard feature is disabled (old dashboard)', () => {
+    beforeEach(() => {
+      spyOn(featureTogglesService, 'isFeatureEnabled').and.returnValue(false);
+      fixture.detectChanges();
+    });
+
+    it('should show cd-overview in template when dashboard feature is disabled', () => {
+      const overviewElement = fixture.debugElement.query(By.css('[data-testid="cd-overview"]'));
+      const dashboardV3Element = fixture.debugElement.query(
+        By.css('[data-testid="cd-dashboard-v3"]')
+      );
+
+      expect(overviewElement).toBeTruthy();
+      expect(dashboardV3Element).toBeNull();
+    });
+
+    it('should set useDeprecated to true when feature is disabled', () => {
+      expect(component.useDeprecated).toBe(false);
+    });
+  });
 });
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.html
new file mode 100644 (file)
index 0000000..d736a3d
--- /dev/null
@@ -0,0 +1,36 @@
+<div cdsGrid
+     [narrow]="true"
+     [condensed]="false"
+     [fullWidth]="true"
+     class="overview">
+  <div cdsRow
+       [narrow]="true"
+       class="overview-row">
+    <div cdsCol
+         [columnNumbers]="{md: 16, lg: 11}">
+      <cds-tile>Health card</cds-tile>
+    </div>
+    <div cdsCol
+         [columnNumbers]="{md: 16, lg: 5}">
+      <cds-tile>Alerts card</cds-tile>
+    </div>
+  </div>
+  <div cdsRow
+       [narrow]="true"
+       class="overview-row">
+    <div cdsCol
+         [columnNumbers]="{md: 16, lg: 11}">
+      <cds-tile>Storage card</cds-tile>
+    </div>
+    <div cdsCol
+         [columnNumbers]="{md: 16, lg: 5}">
+      <cds-tile>Docs card</cds-tile>
+    </div>
+  </div>
+  <div cdsRow>
+    <div cdsCol
+         [columnNumbers]="{md: 16, lg: 16}">
+      <cds-tile>Performance card</cds-tile>
+    </div>
+  </div>
+</div>
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.scss
new file mode 100644 (file)
index 0000000..a84b2ba
--- /dev/null
@@ -0,0 +1,8 @@
+.overview {
+  margin-top: var(--cds-spacing-05);
+  margin-bottom: var(--cds-spacing-05);
+}
+
+.overview-row {
+  margin-bottom: var(--cds-spacing-05);
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.spec.ts
new file mode 100644 (file)
index 0000000..2774459
--- /dev/null
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { OverviewComponent } from './overview.component';
+
+describe('OverviewComponent', () => {
+  let component: OverviewComponent;
+  let fixture: ComponentFixture<OverviewComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [OverviewComponent]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(OverviewComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.ts
new file mode 100644 (file)
index 0000000..4ba2a89
--- /dev/null
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+import { GridModule, TilesModule } from 'carbon-components-angular';
+
+@Component({
+  selector: 'cd-overview',
+  imports: [GridModule, TilesModule],
+  standalone: true,
+  templateUrl: './overview.component.html',
+  styleUrl: './overview.component.scss'
+})
+export class OverviewComponent {}
index 63b1d762c3417b1421dcfab150b4c381bd9af585..6ff3931bd1479a454286cf7ee70a66492c090963 100644 (file)
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 
 from enum import Enum
-from typing import Dict, List, Optional, Set, no_type_check
+from typing import Dict, List, Optional, Set
 
 import cherrypy
 from mgr_module import CLICommand, Option
@@ -115,7 +115,6 @@ class FeatureToggles(I.CanMgr, I.Setupable, I.HasOptions,
             return ret, '\n'.join(msg), ''
         return {'handle_command': cmd}
 
-    @no_type_check  # https://github.com/python/mypy/issues/7806
     def _get_feature_from_request(self, request):
         try:
             return self.Controller2Feature[
@@ -124,7 +123,6 @@ class FeatureToggles(I.CanMgr, I.Setupable, I.HasOptions,
             return None
 
     @ttl_cache(ttl=CACHE_TTL, maxsize=CACHE_MAX_SIZE)
-    @no_type_check  # https://github.com/python/mypy/issues/7806
     def _is_feature_enabled(self, feature):
         return self.mgr.get_module_option(self.OPTION_FMT.format(feature))