]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Add full page tearsheet component 66810/head
authorAfreen Misbah <afreen@ibm.com>
Tue, 6 Jan 2026 10:47:16 +0000 (16:17 +0530)
committerAfreen Misbah <afreen@ibm.com>
Tue, 6 Jan 2026 15:28:10 +0000 (20:58 +0530)
Fixes https://tracker.ceph.com/issues/74327

-  added "full" page tearsheet
-  the full page tearsheet uses a cancel confirmation modal hence added that as well
-  as per latest carbon guidelines for tearsheet https://carbondesignsystem.com/community/patterns/create-flows/#anatomy-of-a-full-page
-  not added - influencer title and toggle (should be added as per reqs)

Signed-off-by: Afreen Misbah <afreen@ibm.com>
src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.html
src/pybind/mgr/dashboard/frontend/src/app/core/layouts/workbench-layout/workbench-layout.component.scss
src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/confirmation-modal/confirmation-modal.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.scss
src/pybind/mgr/dashboard/frontend/src/app/shared/components/tearsheet/tearsheet.component.ts

index c8a42e6522c1e99f16db8979b3479408e090bfec..3881a424eff1c827c573a24216e3aef4edb89032 100644 (file)
@@ -12,7 +12,9 @@
         <cd-motd></cd-motd>
       </div>
       <cd-context></cd-context>
-      <cd-breadcrumbs></cd-breadcrumbs>
+      <div class="breadcrumbs--padding">
+        <cd-breadcrumbs></cd-breadcrumbs>
+      </div>
       <router-outlet></router-outlet>
       <cds-placeholder></cds-placeholder>
     </div>
index d037420b0a77a725fc0ff92ddcdfdf62afa361ee..2716021cfb668f6dbc37d843cb9ca9b041e7eb9a 100644 (file)
 .container-fluid {
   overflow: auto;
   padding-top: 48px;
+
+  &:has(.tearsheet--full) {
+    padding-left: 0;
+    padding-right: 0;
+    overflow: hidden;
+
+    .breadcrumbs--padding {
+      padding-left: var(--cds-spacing-07);
+    }
+  }
 }
 
 .rgw-dashboard {
index 8fffca31e28dbc2c17e9a84403e95fa918868d81..423d92838bb03d28400e55d2cd9e92db4f7163b4 100644 (file)
   <cd-form-button-panel (submitActionEvent)="onSubmit(confirmationForm.value)"
                         [form]="confirmationForm"
                         [submitText]="buttonText"
+                        [cancelText]="cancelText"
                         [showCancel]="showCancel"
                         [showSubmit]="showSubmit"
+                        [submitBtnType]="submitBtnType"
                         [modalForm]="true"></cd-form-button-panel>
 
 </cds-modal>
index 0c816fe0b7e23607e851159e9709b088daa7356a..64ee069e43357c5d6651a4641294f4240a9116ae 100644 (file)
@@ -22,6 +22,7 @@ export class ConfirmationModalComponent extends BaseModal implements OnInit, OnD
   constructor(
     @Optional() @Inject('titleText') public titleText: string,
     @Optional() @Inject('buttonText') public buttonText: string,
+    @Optional() @Inject('cancelText') public cancelText: string = $localize`Cancel`,
     @Optional() @Inject('onSubmit') public onSubmit: Function,
 
     // One of them is needed
@@ -33,6 +34,7 @@ export class ConfirmationModalComponent extends BaseModal implements OnInit, OnD
     @Optional() @Inject('bodyData') public bodyData?: object,
     @Optional() @Inject('onCancel') public onCancel?: Function,
     @Optional() @Inject('bodyContext') public bodyContext?: object,
+    @Optional() @Inject('submitBtnType') public submitBtnType: string = 'primary',
     @Optional() @Inject('showSubmit') public showSubmit = true,
     @Optional() @Inject('showCancel') public showCancel = true
   ) {
index 9508fafadb6acdfe4334c86ded12eb895214fa11..4a917b3229cc1038c04d9f2ccbb8bd87f54e3c15 100644 (file)
@@ -1,16 +1,92 @@
+<!-- Full Tearsheet -->
+ @if(type === 'full') {
+<div
+  cdsGrid
+  class="tearsheet--full"
+  [useCssGrid]="true"
+  [fullWidth]="true">
+  <div cdsCol
+       class="tearsheet-cols--full"
+       [columnNumbers]="{'lg': 16, 'md': 16, 'sm': 16}">
+    <!-- Tearsheet Header -->
+    <header
+      class="tearsheet-header tearsheet-header--full">
+      <h4 class="cds--type-heading-04 tearsheet-header-title">
+        {{title}}
+      </h4>
+      <p class="cds--type-body-02 tearsheet-header-description">
+        {{description}}
+      </p>
+    </header>
+    <section cdsGrid
+             class="tearsheet-body"
+             [useCssGrid]="true"
+             [fullWidth]="true">
+      <!-- Tearsheet Influencer-->
+      <div cdsCol
+           [columnNumbers]="{'lg': 3, 'md': 3, 'sm': 3}"
+           class="tearsheet-influencer">
+        <cds-progress-indicator
+          orientation="vertical"
+          [steps]="steps"
+          [current]="currentStep"
+          spacing="equal"
+          (stepSelected)="onStepSelect($event)">
+        </cds-progress-indicator>
+      </div>
+      <div cdsCol
+           [columnNumbers]="{'lg': 13, 'md': 13, 'sm': 13}"
+           class="tearsheet-main">
+        <!-- Tearsheet Content Area -->
+        <div class="tearsheet-content tearsheet-content--full">
+        <ng-container
+          *ngTemplateOutlet="activeStepTemplate">
+        </ng-container>
+        </div>
+        <!-- Tearsheet Footer -->
+        <cds-modal-footer class="tearsheet-footer tearsheet-footer--full">
+          <button cdsButton="ghost"
+                  class="tearsheet-footer-cancel"
+                  (click)="closeTearsheet()"
+                  size="xl"
+                  i18n>Cancel</button>
+          <button cdsButton="secondary"
+                  size="xl"
+                  [disabled]="currentStep === 0"
+                  (click)="onPrevious()"
+                  i18n>Previous</button>
+          @if (currentStep === lastStep) {
+          <button cdsButton="primary"
+                  size="xl"
+                  (click)="onSubmit()"
+                  i18n>{{submitButtonLabel}}</button>
+          }
+          @else {
+          <button cdsButton="primary"
+                  size="xl"
+                  (click)="onNext()"
+                  i18n>Next</button>
+          }
+        </cds-modal-footer>
+      </div>
+    </section>
+  </div>
+</div>
+}
+@else {
 <!-- Wide Tearsheet -->
 <cds-modal
   size="lg"
   [open]="isOpen"
-  (overlaySelected)="closeWizard()">
+  (overlaySelected)="closeTearsheet()">
   <!-- Tearsheet Header -->
   <header
     class="tearsheet-header">
     <h4 cdsModalHeaderHeading
-        class="cds--type-heading-04 tearsheet-title">
+        class="cds--type-heading-04 tearsheet-header-title">
         {{title}}
     </h4>
-    <p class="cds--type-body-02 tearsheet-description">
+    <p class="cds--type-body-02 tearsheet-header-description">
       {{description}}
     </p>
   </header>
       <cds-modal-footer class="tearsheet-footer">
         <button cdsButton="ghost"
                 class="tearsheet-footer-cancel"
-                (click)="closeWizard()"
+                (click)="closeTearsheet()"
                 size="xl"
                 i18n>Cancel</button>
         <button cdsButton="secondary"
     </div>
   </section>
 </cds-modal>
+}
index c72bcd6560a29156645474a39e6597c1721842b1..605f7133cefb67264e1ec2277039ddffaa2a3adc 100644 (file)
@@ -1,3 +1,4 @@
+// WIDE TEARSHEET
 // No css variable to apply css to modal div hence using css ngdeep
 // This is needed to set the width of tearsheet as per carbon standards.
 :host ::ng-deep .cds--modal-container {
@@ -7,22 +8,42 @@
   max-block-size: calc(100% - 5.5rem);
 }
 
+// FULL TEARSHEET
+.tearsheet--full {
+  height: 100%;
+  width: 100%;
+  margin: 0;
+  padding: 0;
+}
+
+.tearsheet-cols--full {
+  margin: 0;
+  padding: 0;
+}
+
+// HEADER
 .tearsheet-header {
   fill: var(--cds-icon-primary);
   background-color: var(--cds-layer-01);
   padding: var(--cds-spacing-06) var(--cds-spacing-07);
   border-block-end: 1px solid var(--cds-border-subtle-01);
 
-  .tearsheet-title {
+  &-title {
     color: var(--cds-text-primary);
   }
 
-  .tearsheet-description {
+  &-description {
     margin-top: var(--cds-spacing-04);
     color: var(--cds-text-secondary);
   }
+
+  &--full {
+    position: sticky;
+    padding: 0 0 var(--cds-spacing-05) var(--cds-spacing-07);
+  }
 }
 
+// BODY
 .tearsheet-body {
   padding-block: 0;
   padding-inline: 0;
       padding: var(--cds-spacing-06) var(--cds-spacing-07);
       flex: 1;
       overflow-y: auto;
+
+      &--full {
+        padding-left: 0;
+      }
     }
   }
 }
 
+//FOOTER
 .tearsheet-footer {
   border-top: 1px solid var(--cds-border-subtle);
   background: var(--cds-background);
 
-  .tearsheet-footer-cancel {
+  &-cancel {
     margin-left: var(--cds-spacing-05);
   }
+
+  &--full {
+    position: sticky;
+    bottom: 0;
+  }
 }
index 01e56d2dc874b2312b4068cfaa58460245add2d1..a4651564054a49b2336ccc1ed2e12a042f9f99ef 100644 (file)
@@ -15,6 +15,7 @@ import { TearsheetStepComponent } from '../tearsheet-step/tearsheet-step.compone
 import { ModalCdsService } from '../../services/modal-cds.service';
 import { ActivatedRoute } from '@angular/router';
 import { Location } from '@angular/common';
+import { ConfirmationModalComponent } from '../confirmation-modal/confirmation-modal.component';
 
 @Component({
   selector: 'cd-tearsheet',
@@ -26,6 +27,8 @@ export class TearsheetComponent implements OnInit, AfterViewChecked {
   @Input() title!: string;
   @Input() steps!: Array<Step>;
   @Input() description!: string;
+  @Input() submitButtonLabel: string = $localize`Create`;
+  @Input() type: 'full' | 'wide' = 'wide';
 
   @Output() submitRequested = new EventEmitter<void>();
 
@@ -58,7 +61,15 @@ export class TearsheetComponent implements OnInit, AfterViewChecked {
     this.currentStep = event.index;
   }
 
-  closeWizard() {
+  closeTearsheet() {
+    if (this.type === 'full') {
+      this.closeFullTearsheet();
+    } else {
+      this.closeWideTearsheet();
+    }
+  }
+
+  closeWideTearsheet() {
     this.isOpen = false;
     if (this.hasModalOutlet) {
       this.location.back();
@@ -85,6 +96,22 @@ export class TearsheetComponent implements OnInit, AfterViewChecked {
     }
   }
 
+  closeFullTearsheet() {
+    this.cdsModalService.show(ConfirmationModalComponent, {
+      titleText: $localize`Are you sure you want to cancel ?`,
+      description: $localize`If you cancel, the information you have entered won't be saved.`,
+      buttonText: $localize`Cancel`,
+      cancelText: $localize`Return to form`,
+      onSubmit: () => {
+        this.isOpen = false;
+        this.cdsModalService.dismissAll();
+        this.location.back();
+      },
+      submitBtnType: 'danger',
+      showCancel: true
+    });
+  }
+
   ngAfterViewChecked() {
     this.changeDetectorRef.detectChanges();
   }