]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Added query tital and used capacity data
authorAfreen Misbah <afreen@ibm.com>
Mon, 9 Feb 2026 07:28:16 +0000 (12:58 +0530)
committerAfreen Misbah <afreen@ibm.com>
Thu, 12 Feb 2026 09:49:59 +0000 (15:19 +0530)
Signed-off-by: Afreen Misbah <afreen@ibm.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/overview.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/storage-card/overview-storage-card.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/overview/storage-card/overview-storage-card.component.ts

index 30b7fa30cd00f711cb3971cf3ac869e237522505..a765474a6f014e671a9f469e62c6fd19546818fd 100644 (file)
@@ -21,7 +21,9 @@
     <div cdsCol
          class="cds-mb-5"
          [columnNumbers]="{lg: 16}">
-      <cd-overview-storage-card></cd-overview-storage-card>
+      <cd-overview-storage-card
+        [total]="totalCapacity"
+        [used]="usedCapacity"></cd-overview-storage-card>
     </div>
   </div>
   <div cdsRow>
index 09d97324fd167107076f7eafa5122bfa7636ad84..3f1f100999b9f9541fd8781f07e2fe51cbfc858b 100644 (file)
@@ -1,6 +1,11 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
 import { GridModule, TilesModule } from 'carbon-components-angular';
 import { OverviewStorageCardComponent } from './storage-card/overview-storage-card.component';
+import { HealthService } from '~/app/shared/api/health.service';
+import { HealthSnapshotMap } from '~/app/shared/models/health.interface';
+import { RefreshIntervalService } from '~/app/shared/services/refresh-interval.service';
+import { catchError, exhaustMap, takeUntil } from 'rxjs/operators';
+import { EMPTY, Subject } from 'rxjs';
 
 @Component({
   selector: 'cd-overview',
@@ -9,4 +14,32 @@ import { OverviewStorageCardComponent } from './storage-card/overview-storage-ca
   templateUrl: './overview.component.html',
   styleUrl: './overview.component.scss'
 })
-export class OverviewComponent {}
+export class OverviewComponent implements OnInit {
+  totalCapacity: number;
+  usedCapacity: number;
+  private destroy$ = new Subject<void>();
+
+
+  constructor(private healthService: HealthService, private refreshIntervalService: RefreshIntervalService) {}
+
+  ngOnInit(): void {
+    this.refreshIntervalObs(() =>  this.healthService.getHealthSnapshot()).subscribe({
+      next: (healthData: HealthSnapshotMap) => {
+      this.totalCapacity = healthData?.pgmap?.bytes_total;
+      this.usedCapacity = healthData?.pgmap?.bytes_used;
+  }});
+  }
+
+   refreshIntervalObs(fn: Function) {
+      return this.refreshIntervalService.intervalData$.pipe(
+        exhaustMap(() => fn().pipe(catchError(() => EMPTY))),
+        takeUntil(this.destroy$)
+      );
+    }
+
+  ngOnDestroy() {
+    this.destroy$.next();
+    this.destroy$.complete();
+  }
+
+}
index 556f08e7d19fd8ef709eda1e0d75606cb587d9d3..70f1dd91858e43778c109d35d7799156c8fae0f7 100644 (file)
     <h5>
       <span
         class="cds--type-heading-05"
-        i18n>200{{' '}}</span>
+        i18n>{{usedRaw}}{{' '}}</span>
       <span
         class="cds--type-body-02"
-        i18n>TB of 1300 TB used</span>
+        i18n>{{usedRawUnit}} of {{totalRaw}} {{totalRawUnit}} used</span>
     </h5>
     <cds-tooltip
       [autoAlign]="true"
index 1db7cb7917f38f4c29bcdbb6b06ecf5464c1c9d4..bd8cf522f681ca0de504cee0972de69bd3eed01d 100644 (file)
@@ -1,4 +1,4 @@
-import { Component, ViewEncapsulation } from '@angular/core';
+import { Component, Input, OnChanges, ViewEncapsulation } from '@angular/core';
 import {
   CheckboxModule,
   DropdownModule,
@@ -8,6 +8,7 @@ import {
 } from 'carbon-components-angular';
 import { ProductiveCardComponent } from '~/app/shared/components/productive-card/productive-card.component';
 import { MeterChartComponent, MeterChartOptions } from '@carbon/charts-angular';
+import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
 
 const StorageType = {
   ALL: $localize`All`,
@@ -16,6 +17,30 @@ const StorageType = {
   OBJECT: $localize`Object`
 };
 
+// const Query = {
+//   RAW: {
+//     [StorageType.ALL]: `sum by (application) (ceph_pool_bytes_used * on(pool_id) group_left(instance, name, application) ceph_pool_metadata{application=~"(.*Block.*)|(.*Filesystem.*)|(.*Object.*)|(..*)"})`,
+//     [StorageType.BLOCK]: "",
+//     [StorageType.FILE]: "",
+//     [StorageType.OBJECT]: ""
+//   },
+//   USED: {
+//     [StorageType.ALL]: `sum by (application) (ceph_pool_stored * on(pool_id) group_left(instance, name, application) ceph_pool_metadata{application=~"(.*Block.*)|(.*Filesystem.*)|(.*Object.*)|(..*)"})`,
+//     [StorageType.BLOCK]: "",
+//     [StorageType.FILE]: "",
+//     [StorageType.OBJECT]: ""
+//   }
+// }
+
+/**
+ * 1. Fetch snapshot query -> [pass total and used raw]
+ * 2. Show the usage title -> always fixed
+ * 3. The chart total -> raw total always fixed
+ * 4. Set data for block, file , object, all -> raw, sep queries
+ * 5. Set data for block, file object + replicated -> usable
+ * 6. Dont show what is 0
+ */
+
 @Component({
   selector: 'cd-overview-storage-card',
   imports: [
@@ -32,12 +57,18 @@ const StorageType = {
   styleUrl: './overview-storage-card.component.scss',
   encapsulation: ViewEncapsulation.None
 })
-export class OverviewStorageCardComponent {
+export class OverviewStorageCardComponent implements OnChanges {
+  @Input() total!: number;
+  @Input() used!: number;
+  totalRaw: string;
+  usedRaw: string;
+  totalRawUnit: string;
+  usedRawUnit: string;
   options: MeterChartOptions = {
     height: '45px',
     meter: {
       proportional: {
-        total: 2000,
+        total: null,
         unit: 'GB',
         breakdownFormatter: (_e) => null,
         totalFormatter: (_e) => null
@@ -58,16 +89,15 @@ export class OverviewStorageCardComponent {
   allData = [
     {
       group: StorageType.BLOCK,
-      value: 202
+      value: 100,
     },
     {
       group: StorageType.FILE,
-      value: 654
+      value: 105
     },
     {
       group: StorageType.OBJECT,
-      value: 120
-    }
+      value: 60    }
   ];
   dropdownItems = [
     { content: StorageType.ALL },
@@ -79,6 +109,40 @@ export class OverviewStorageCardComponent {
   selectedStorageType: string = StorageType.ALL;
   displayData = this.allData;
 
+  constructor(private dimlessBinaryPipe: DimlessBinaryPipe) {}
+
+ngOnChanges(): void {
+  if (this.total == null || this.used == null) return;
+
+  const totalRaw = this.dimlessBinaryPipe.transform(this.total);
+  const usedRaw = this.dimlessBinaryPipe.transform(this.used);
+
+  const [totalValue, totalUnit] = totalRaw.split(/\s+/);
+  const [usedValue, usedUnit] = usedRaw.split(/\s+/);
+
+  const cleanedTotal = Number(totalValue.replace(/,/g, '').trim());
+
+  if (Number.isNaN(cleanedTotal)) return;
+
+  this.totalRaw = totalValue;
+  this.totalRawUnit = totalUnit;
+  this.usedRaw = usedValue;
+  this.usedRawUnit = usedUnit;
+
+  // chart reacts to 'options' and 'data' changes only, hence mandatory to replace whole object
+  this.options = {
+    ...this.options,
+    meter: {
+      ...this.options.meter,
+      proportional: {
+        ...this.options.meter.proportional,
+        total: cleanedTotal,
+        unit: totalUnit
+      }
+    }
+  };
+}
+
   toggleRawCapacity(isChecked: boolean) {
     this.isRawCapacity = isChecked;
   }