From 92d36970fb007b45f8c9e9c9156749158e17f152 Mon Sep 17 00:00:00 2001 From: Afreen Misbah Date: Wed, 14 Jan 2026 02:17:40 +0530 Subject: [PATCH] mgr/dashboard: Add productive card component - add generic productive card component - based on carbon design system - there are two versions of card - with shadow(tinted affect) and without. - applies gray10 theme which is decided by new designs. Fixes https://tracker.ceph.com/issues/74450 Signed-off-by: Afreen Misbah (cherry picked from commit aa2216d8d5e728b7ed7637e190a93717e86c8dc6) Conflicts: src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard/dashboard-v3.component.scss src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/dashboard.module.ts src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts --- .../shared/components/components.module.ts | 15 ++++-- .../productive-card.component.html | 31 ++++++++++++ .../productive-card.component.scss | 48 +++++++++++++++++++ .../productive-card.component.spec.ts | 24 ++++++++++ .../productive-card.component.ts | 38 +++++++++++++++ 5 files changed, 152 insertions(+), 4 deletions(-) create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.html create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.scss create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.spec.ts create mode 100644 src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.ts 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 8b20898dbe8..9aff468cdc0 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 @@ -39,7 +39,9 @@ import { InlineLoadingModule, PanelModule, TagModule, - LinkModule + LinkModule, + LayerModule, + TilesModule } from 'carbon-components-angular'; import { MotdComponent } from '~/app/shared/components/motd/motd.component'; @@ -92,6 +94,7 @@ import CopyIcon from '@carbon/icons/es/copy/32'; import { IconComponent } from './icon/icon.component'; import downloadIcon from '@carbon/icons/es/download/16'; import { ChartsModule } from '@carbon/charts-angular'; +import { ProductiveCardComponent } from './productive-card/productive-card.component'; @NgModule({ imports: [ @@ -135,7 +138,9 @@ import { ChartsModule } from '@carbon/charts-angular'; PanelModule, ChartsModule, TagModule, - LinkModule + LinkModule, + LayerModule, + TilesModule ], declarations: [ SparklineComponent, @@ -180,7 +185,8 @@ import { ChartsModule } from '@carbon/charts-angular'; ProgressComponent, IconComponent, TearsheetComponent, - TearsheetStepComponent + TearsheetStepComponent, + ProductiveCardComponent ], providers: [provideCharts(withDefaultRegisterables())], exports: [ @@ -222,7 +228,8 @@ import { ChartsModule } from '@carbon/charts-angular'; ProgressComponent, IconComponent, TearsheetComponent, - TearsheetStepComponent + TearsheetStepComponent, + ProductiveCardComponent ] }) export class ComponentsModule { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.html new file mode 100644 index 00000000000..67a4cbfaee4 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.html @@ -0,0 +1,31 @@ + +
+

+ {{title}} +

+ @if(headerActionTemplate) { +
+ +
+ } +
+
+ +
+ @if(footerTemplate) { +
+ +
+ } +
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.scss new file mode 100644 index 00000000000..cdab967d01e --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.scss @@ -0,0 +1,48 @@ +@use '@carbon/colors'; + +.productive-card { + margin: 0; + padding: 0; + + &-header { + margin: 0; + padding: var(--cds-spacing-05); + + &-title { + margin: 0; + } + + &-actions { + margin: 0; + } + } + + &-section { + margin: 0; + padding: var(--cds-spacing-05); + padding-top: 0; + + &--footer { + padding-bottom: 0; + } + } + + &-footer { + height: var(--cds-spacing-08); + padding: var(--cds-spacing-05); + } + + &--shadow { + background-color: var(--cds-layer); + background-image: + // cyan left edge + radial-gradient(120% 60% at -15% 100%, rgba(colors.$cyan-60, 0.13) 0%, transparent 65%), + // cyan right edge + radial-gradient(120% 60% at 115% 100%, rgba(colors.$cyan-60, 0.1) 0%, transparent 65%), + // pink center + radial-gradient(120% 60% at 50% 100%, rgba(colors.$magenta-60, 0.11) 0%, transparent 70%); + box-shadow: var(--cds-ai-drop-shadow), inset 0 0 0 1px var(--cds-ai-inner-shadow); + overflow: hidden; // ensures proper edge fade + position: relative; + } +} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.spec.ts new file mode 100644 index 00000000000..0fe568b44db --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ProductiveCardComponent } from './productive-card.component'; +import { GridModule, LayerModule, TilesModule } from 'carbon-components-angular'; + +describe('ProductiveCardComponent', () => { + let component: ProductiveCardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ProductiveCardComponent], + imports: [GridModule, LayerModule, TilesModule] + }).compileComponents(); + + fixture = TestBed.createComponent(ProductiveCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.ts new file mode 100644 index 00000000000..7047a1a3c68 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/productive-card/productive-card.component.ts @@ -0,0 +1,38 @@ +import { Component, ContentChild, Input, TemplateRef } from '@angular/core'; + +/** + * A generic productive card component. + * + * @example + * + * ... + * ... + *

My card body content

+ *
+ */ +@Component({ + selector: 'cd-productive-card', + standalone: false, + templateUrl: './productive-card.component.html', + styleUrl: './productive-card.component.scss' +}) +export class ProductiveCardComponent { + /* Card Title */ + @Input() title!: string; + + /* Optional: Applies a tinted-colored background to card */ + @Input() applyShadow: boolean = false; + + /* Optional: Header action template, appears alongwith title in top-right corner */ + @ContentChild('headerAction', { + read: TemplateRef + }) + headerActionTemplate?: TemplateRef; + + /* Optional: Footer template , otherwise no footer will be used for card.*/ + @ContentChild('footer', { + read: TemplateRef + }) + footerTemplate?: TemplateRef; +} -- 2.47.3