]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Add generic component for icons
authorAfreen Misbah <afreen@ibm.com>
Thu, 3 Jul 2025 11:09:25 +0000 (16:39 +0530)
committerAfreen Misbah <afreen@ibm.com>
Tue, 26 Aug 2025 13:37:00 +0000 (19:07 +0530)
Fixes https://tracker.ceph.com/issues/71947
Fixes https://tracker.ceph.com/issues/71933

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

 Conflicts:
src/pybind/mgr/dashboard/frontend/src/app/shared/components/card-row/card-row.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts
src/pybind/mgr/dashboard/frontend/src/styles/_carbon-defaults.scss

src/pybind/mgr/dashboard/frontend/src/app/shared/components/card-row/card-row.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.html [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.scss [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts

index c8464ea5518851a92f2a7c87ee4d308f1c209885..2a41e3e7faaab2e6f406f25666003e715dba0f43 100644 (file)
     <span *ngIf="data.categoryPgAmount?.clean">
       {{ data.categoryPgAmount?.clean }}
     </span>
-    <i class="text-success"
-       [ngClass]="[icons.success]">
-    </i>
+    <cd-icon
+       type="success">
+    </cd-icon >
   </span>
   <span *ngIf="data.info"
         class="ms-2">
     <span *ngIf="data.info">
       {{ data.info }}
     </span>
-    <i class="text-info"
-       [ngClass]="[icons.danger]">
-    </i>
+    <cd-icon
+       type="info">
+    </cd-icon >
   </span>
   <span *ngIf="data.warn || data.categoryPgAmount?.warning"
         class="ms-2">
@@ -82,9 +82,9 @@
     <span *ngIf="data.categoryPgAmount?.warning">
       {{ data.categoryPgAmount?.warning }}
     </span>
-    <i class="text-warning"
-       [ngClass]="[icons.warning]">
-    </i>
+    <cd-icon
+       type="warning">
+    </cd-icon >
   </span>
   <span *ngIf="data.error || data.categoryPgAmount?.unknown"
         class="ms-2">
@@ -94,9 +94,9 @@
     <span *ngIf="data.categoryPgAmount?.unknown">
       {{ data.categoryPgAmount?.unknown }}
     </span>
-    <i class="text-danger"
-       [ngClass]="[icons.danger]">
-    </i>
+    <cd-icon
+       type="danger">
+    </cd-icon >
   </span>
   <span *ngIf="data.categoryPgAmount?.working"
         class="ms-2">
   </span>
   }
 </ng-template>
-
+<cd-icon
+       type="progress">
+    </cd-icon >
 <ng-template #osdSummary>
   @if (data === null) {
   <ng-container *ngTemplateOutlet="loadingTpl"></ng-container>
   } @else {
   <span *ngIf="data.up === data.in">
     {{ data.up }}
-    <i class="text-success"
-       [ngClass]="[icons.success]">
-    </i>
+    <cd-icon
+       type="success">
+    </cd-icon >
   </span>
   <span *ngIf="data.up !== data.in">
     {{ data.up }}
   <ng-container *ngTemplateOutlet="loadingTpl"></ng-container>
   } @else {
   <span>
-    {{ data?.up }}
-    <i class="text-success"
-       *ngIf="data?.up || data?.up === 0"
-       [ngClass]="[icons.success]">
-    </i>
+    {{ data.up }}
+    <cd-icon
+       *ngIf="data.up || data.up === 0"
+       type="success">
+    </cd-icon >
   </span>
   <span *ngIf="data?.down"
         class="ms-2">
-        {{ data?.down }}
-    <i class="text-danger"
-       [ngClass]="[icons.danger]">
-    </i>
+        {{ data.down }}
+    <cd-icon
+       type="danger">
+    </cd-icon >
   </span>
 
   }
   @if (data === 0 || data) {
   <span *ngIf="!dropdownTotalError else showErrorNum">
     {{ data }}
-    <i class="text-success"
-       [ngClass]="[icons.success]"></i>
+    <cd-icon
+       type="success"></cd-icon >
   </span>
   } @else {
     <ng-container *ngTemplateOutlet="loadingTpl"></ng-container>
   <ng-template #showErrorNum>
     <span *ngIf="data - dropdownTotalError  > 0">
       {{ data - dropdownTotalError  }}
-    <i class="text-success"
-       [ngClass]="[icons.success]"></i>
+    <cd-icon
+      type="success"></cd-icon >
     </span>
     <span>
       {{ dropdownTotalError  }}
-      <i class="text-danger"
-         [ngClass]="[icons.danger]"></i>
+      <cd-icon
+        type="danger"></cd-icon >
     </span>
   </ng-template>
 </ng-template>
         </div>
         <span [ngClass]="data.value.error ? 'me-2' : 'me-4'">
           {{ data.value.ok }}
-          <i class="text-success"
+          <cd-icon
              *ngIf="data.value.ok"
-             [ngClass]="[icons.success]">
-          </i>
+             type="success">
+          </cd-icon >
         </span>
         <span *ngIf="data.value.error"
               class="me-4 ms-2">
               {{ data.value.error }}
-          <i class="text-danger"
-             [ngClass]="[icons.danger]">
-          </i>
+          <cd-icon
+             type="danger">
+          </cd-icon >
         </span>
       </div>
     </li>
index 5baf3878cb39778b9f52544591f9ccf8aa90aa28..b0566c7319ccb2498639e7c0f41c1bb190cdf4fd 100644 (file)
@@ -85,6 +85,7 @@ import { ProgressComponent } from './progress/progress.component';
 // Icons
 import InfoIcon from '@carbon/icons/es/information/16';
 import CopyIcon from '@carbon/icons/es/copy/32';
+import { IconComponent } from './icon/icon.component';
 
 @NgModule({
   imports: [
@@ -166,7 +167,8 @@ import CopyIcon from '@carbon/icons/es/copy/32';
     HelpTextComponent,
     FormAdvancedFieldsetComponent,
     UpgradableComponent,
-    ProgressComponent
+    ProgressComponent,
+    IconComponent
   ],
   providers: [provideCharts(withDefaultRegisterables())],
   exports: [
@@ -205,7 +207,8 @@ import CopyIcon from '@carbon/icons/es/copy/32';
     HelpTextComponent,
     FormAdvancedFieldsetComponent,
     UpgradableComponent,
-    ProgressComponent
+    ProgressComponent,
+    IconComponent
   ]
 })
 export class ComponentsModule {
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.html
new file mode 100644 (file)
index 0000000..2e6522b
--- /dev/null
@@ -0,0 +1,23 @@
+@if (type === ICON_TYPE.danger) {
+    <svg class = "danger-icon"
+         [cdsIcon]="ICONS.danger"
+         [size]="size"></svg>
+}
+
+@if (type === ICON_TYPE.info) {
+    <svg class = "info-icon"
+         [cdsIcon]="ICONS.infoCircle"
+         [size]="size"></svg>
+}
+
+@if (type === ICON_TYPE.success) {
+    <svg class = "success-icon"
+         [cdsIcon]="ICONS.success"
+         [size]="size"></svg>
+}
+
+@if (type === ICON_TYPE.warning) {
+    <svg class = "warning-icon"
+         [cdsIcon]="ICONS.warning"
+         [size]="size"></svg>
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.scss
new file mode 100644 (file)
index 0000000..e0a3d20
--- /dev/null
@@ -0,0 +1,17 @@
+@use '@carbon/styles/scss/theme';
+
+.success-icon {
+  color: theme.$support-success;
+}
+
+.danger-icon {
+  color: theme.$support-error;
+}
+
+.info-icon {
+  color: theme.$support-info;
+}
+
+.warning-icon {
+  color: theme.$support-caution-major;
+}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.spec.ts
new file mode 100644 (file)
index 0000000..c144594
--- /dev/null
@@ -0,0 +1,22 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { IconComponent } from './icon.component';
+
+describe('IconComponent', () => {
+  let component: IconComponent;
+  let fixture: ComponentFixture<IconComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [IconComponent]
+    }).compileComponents();
+
+    fixture = TestBed.createComponent(IconComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.ts
new file mode 100644 (file)
index 0000000..82bb198
--- /dev/null
@@ -0,0 +1,15 @@
+import { Component, Input } from '@angular/core';
+import { ICON_TYPE, Icons, IconsSize } from '../../enum/icons.enum';
+
+@Component({
+  selector: 'cd-icon',
+  templateUrl: './icon.component.html',
+  styleUrl: './icon.component.scss'
+})
+export class IconComponent {
+  @Input() type!: keyof typeof ICON_TYPE;
+  @Input() size: IconsSize = IconsSize.size16;
+
+  readonly ICONS = Icons;
+  readonly ICON_TYPE = ICON_TYPE;
+}
index 1938e325378b62222ea71caeb5b6253e189ee3a8..458ca296f60a72d799519ebfb8d7503de4642a4a 100644 (file)
@@ -97,3 +97,17 @@ export enum Icons {
   spin = 'fa fa-spin', //  To get any icon to rotate
   inverse = 'fa fa-inverse' // To get an alternative icon color
 }
+
+export enum IconsSize {
+  size16 = '16',
+  size20 = '20',
+  size24 = '24',
+  size32 = '32'
+}
+
+export const ICON_TYPE = {
+  danger: 'warning--filled',
+  info: 'information--filled',
+  success: 'checkmark--filled',
+  warning: 'warning--alt--filled'
+} as const;
\ No newline at end of file