]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Expand Cluster improvements 57927/head
authorNaman Munet <namanmunet@Namans-MacBook-Pro.local>
Fri, 7 Jun 2024 10:49:23 +0000 (16:19 +0530)
committerNaman Munet <namanmunet@Namans-MacBook-Pro.local>
Fri, 21 Jun 2024 01:50:12 +0000 (07:20 +0530)
worked on expand cluster screen hide/show and persisting osd form values

Fixes: https://tracker.ceph.com/issues/66344
Signed-off-by: Naman Munet <nmunet@redhat.com>
17 files changed:
src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/create-cluster.po.ts
src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/osds.po.ts
src/pybind/mgr/dashboard/frontend/cypress/e2e/common/urls.po.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster-review.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/create-cluster/create-cluster.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-form/osd-form.component.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/auth/login/login.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/api/osd.service.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/constants/app.constants.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts

index 300eddbcc3de8c676cd937ac31e7c9a01746e98b..2ec31869daf7e01fd067b4ae8e03a09efabdab7f 100644 (file)
@@ -4,7 +4,7 @@ import { HostsPageHelper } from './hosts.po';
 import { ServicesPageHelper } from './services.po';
 
 const pages = {
-  index: { url: '#/expand-cluster', id: 'cd-create-cluster' }
+  index: { url: '#/expand-cluster?welcome=true', id: 'cd-create-cluster' }
 };
 export class CreateClusterWizardHelper extends PageHelper {
   pages = pages;
@@ -28,7 +28,7 @@ export class CreateClusterWizardHelper extends PageHelper {
 
 export class CreateClusterHostPageHelper extends HostsPageHelper {
   pages = {
-    index: { url: '#/expand-cluster', id: 'cd-wizard' },
+    index: { url: '#/expand-cluster?welcome=true', id: 'cd-wizard' },
     add: { url: '', id: 'cd-host-form' }
   };
 
@@ -42,7 +42,7 @@ export class CreateClusterHostPageHelper extends HostsPageHelper {
 
 export class CreateClusterServicePageHelper extends ServicesPageHelper {
   pages = {
-    index: { url: '#/expand-cluster', id: 'cd-wizard' },
+    index: { url: '#/expand-cluster?welcome=true', id: 'cd-wizard' },
     create: { url: '', id: 'cd-service-form' }
   };
 
index cd812f474fb89ae9d55a3275d5181954e79f7725..e96518bceb70c191c4cbeb876c15933c6124fb9e 100644 (file)
@@ -15,6 +15,11 @@ export class OSDsPageHelper extends PageHelper {
 
   create(deviceType: 'hdd' | 'ssd', hostname?: string, expandCluster = false) {
     cy.get('[aria-label="toggle advanced mode"]').click();
+    cy.get('[aria-label="toggle advanced mode"]').then(($button) => {
+      if ($button.hasClass('collapsed')) {
+        cy.wrap($button).click();
+      }
+    });
     // Click Primary devices Add button
     cy.get('cd-osd-devices-selection-groups[name="Primary"]').as('primaryGroups');
     cy.get('@primaryGroups').find('button').click();
index 6f7316f98f59e9a1c8a44c7d98ed88d40b7bb787..d888388cad35d07ce316a76e863aaa50c676d51e 100644 (file)
@@ -3,7 +3,7 @@ import { PageHelper } from '../page-helper.po';
 export class UrlsCollection extends PageHelper {
   pages = {
     // Cluster expansion
-    welcome: { url: '#/expand-cluster', id: 'cd-create-cluster' },
+    welcome: { url: '#/expand-cluster?welcome=true', id: 'cd-create-cluster' },
 
     // Landing page
     dashboard: { url: '#/dashboard', id: 'cd-dashboard' },
index a2ae23b2c2bf4dad8a3ee8e1a1d0d3ee576161ff..df61fd40a9536ef74ff4a6addb61855b209f5f0e 100644 (file)
@@ -9,20 +9,20 @@
               class="bold">Hosts</td>
           <td>{{ hostsCount }}</td>
         </tr>
-        <tr>
+        <tr *ngIf="!isSimpleDeployment; else simpleDeploymentTextTpl">
           <td>
-          <dl>
-            <dt>
-              <p i18n>Storage Capacity</p>
-            </dt>
-            <dd>
-              <p i18n>Number of devices</p>
-            </dd>
-            <dd>
-              <p i18n>Raw capacity</p>
-            </dd>
-          </dl>
-        </td>
+            <dl>
+              <dt>
+                <p i18n>Storage Capacity</p>
+              </dt>
+              <dd>
+                <p i18n>Number of devices</p>
+              </dd>
+              <dd>
+                <p i18n>Raw capacity</p>
+              </dd>
+            </dl>
+          </td>
           <td class="pt-5"><p>{{ totalDevices }}</p><p>
             {{ totalCapacity | dimlessBinary }}</p></td>
         </tr>
     </fieldset>
   </div>
 
-<div class="col-lg-9">
+  <div class="col-lg-9">
   <legend i18n
           class="cd-header">Host Details</legend>
   <cd-hosts [hiddenColumns]="['services', 'status']"
             [hideToolHeader]="true"
             [hasTableDetails]="false"
-            [showGeneralActionsOnly]="true">
-  </cd-hosts>
-</div>
+            [showGeneralActionsOnly]="true"
+            [showExpandClusterBtn]="false">
+    </cd-hosts>
+  </div>
 </div>
+<ng-template #simpleDeploymentTextTpl>
+  <tr>
+    <td>
+      <dl>
+        <dt>
+          <p i18n>Storage Capacity</p>
+        </dt>
+        <dd>
+          <p i18n>{{deploymentDescText}}</p>
+        </dd>
+      </dl>
+    </td>
+  </tr>
+</ng-template>
index 964fd7594e79cb01be44f990e245c6825b896f2d..ed60ddf805ada554141bd2f74c4f53c0591ffae7 100644 (file)
@@ -23,6 +23,8 @@ export class CreateClusterReviewComponent implements OnInit {
   services: Array<CephServiceSpec> = [];
   totalCPUs = 0;
   totalMemory = 0;
+  deploymentDescText: string;
+  isSimpleDeployment = true;
 
   constructor(
     public wizardStepsService: WizardStepsService,
@@ -40,6 +42,7 @@ export class CreateClusterReviewComponent implements OnInit {
     let dbDevices = 0;
     let dbDeviceCapacity = 0;
 
+    this.isSimpleDeployment = this.osdService.isDeployementModeSimple;
     const hostContext = new CdTableFetchDataContext(() => undefined);
     this.hostService.list(hostContext.toParams(), 'true').subscribe((resp: object[]) => {
       this.hosts = resp;
@@ -67,6 +70,21 @@ export class CreateClusterReviewComponent implements OnInit {
       dbDeviceCapacity = this.osdService.osdDevices['db']['capacity'];
     }
 
+    if (this.isSimpleDeployment) {
+      this.osdService.getDeploymentOptions().subscribe((optionsObj) => {
+        if (!_.isEmpty(optionsObj)) {
+          Object.keys(optionsObj.options).forEach((option) => {
+            if (
+              this.osdService.selectedFormValues &&
+              this.osdService.selectedFormValues.get('deploymentOption').value === option
+            ) {
+              this.deploymentDescText = optionsObj.options[option].desc;
+            }
+          });
+        }
+      });
+    }
+
     this.totalDevices = dataDevices + walDevices + dbDevices;
     this.osdService.osdDevices['totalDevices'] = this.totalDevices;
     this.totalCapacity = dataDeviceCapacity + walDeviceCapacity + dbDeviceCapacity;
index 272b5b0b9161770a13b8278b580d5a8bf82557fd..930c6b42ac9c7cffa083deef87bc6851320ae408 100644 (file)
@@ -1,5 +1,5 @@
 <div class="container h-75"
-     *ngIf="!startClusterCreation">
+     *ngIf="startClusterCreation">
   <div class="row h-100 justify-content-center align-items-center">
     <div class="blank-page">
       <!-- htmllint img-req-src="false" -->
@@ -30,7 +30,7 @@
 </div>
 
 <div class="card"
-     *ngIf="startClusterCreation">
+     *ngIf="!startClusterCreation">
   <div class="card-header"
        i18n>Expand Cluster</div>
   <div class="container-fluid">
@@ -45,7 +45,8 @@
           <cd-hosts [hiddenColumns]="['services']"
                     [hideMaintenance]="true"
                     [hasTableDetails]="false"
-                    [showGeneralActionsOnly]="true"></cd-hosts>
+                    [showGeneralActionsOnly]="true"
+                    [showExpandClusterBtn]="false"></cd-hosts>
         </div>
         <div *ngSwitchCase="'2'"
              class="ms-5">
index ca3435536067b50c06456f115bd3c0cc0e6da96f..943d5c8ff1627bdb127e896c65ff7d672f7711c6 100644 (file)
@@ -59,6 +59,8 @@ describe('CreateClusterComponent', () => {
   });
 
   it('should have project name as heading in welcome screen', () => {
+    component.startClusterCreation = true;
+    fixture.detectChanges();
     const heading = fixture.debugElement.query(By.css('h3')).nativeElement;
     expect(heading.innerHTML).toBe(`Welcome to ${projectConstants.projectName}`);
   });
index 670a3e00dfe5bbcee3b47c2fd16b5b3560bed637..25d87175130640dbaa8c5ecc98809bd33f48f165 100644 (file)
@@ -7,7 +7,7 @@ import {
   TemplateRef,
   ViewChild
 } from '@angular/core';
-import { Router } from '@angular/router';
+import { ActivatedRoute, Router } from '@angular/router';
 
 import { NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
 import _ from 'lodash';
@@ -68,7 +68,8 @@ export class CreateClusterComponent implements OnInit, OnDestroy {
     private clusterService: ClusterService,
     private modalService: ModalService,
     private taskWrapper: TaskWrapperService,
-    private osdService: OsdService
+    private osdService: OsdService,
+    private route: ActivatedRoute
   ) {
     this.permissions = this.authStorageService.getPermissions();
     this.currentStepSub = this.wizardStepsService
@@ -80,6 +81,14 @@ export class CreateClusterComponent implements OnInit, OnDestroy {
   }
 
   ngOnInit(): void {
+    this.route.queryParams.subscribe((params) => {
+      // reading 'welcome' value true/false to toggle expand-cluster wizand view and welcome view
+      const showWelcomeScreen = params['welcome'];
+      if (showWelcomeScreen) {
+        this.startClusterCreation = showWelcomeScreen;
+      }
+    });
+
     this.osdService.getDeploymentOptions().subscribe((options) => {
       this.deploymentOption = options;
       this.selectedOption = { option: options.recommended_option, encrypted: false };
@@ -91,7 +100,7 @@ export class CreateClusterComponent implements OnInit, OnDestroy {
   }
 
   createCluster() {
-    this.startClusterCreation = true;
+    this.startClusterCreation = false;
   }
 
   skipClusterCreation() {
@@ -244,5 +253,6 @@ export class CreateClusterComponent implements OnInit, OnDestroy {
 
   ngOnDestroy(): void {
     this.currentStepSub.unsubscribe();
+    this.osdService.selectedFormValues = null;
   }
 }
index c02b29d101f6a0893692ff9ff14c2cf0cb58beaf..43d41c8ce7f999f1dc5fe7202954af8b8c0771ea 100644 (file)
                             id="host-actions"
                             [tableActions]="tableActions">
           </cd-table-actions>
+          <cd-table-actions [permission]="permissions.hosts"
+                            [selection]="selection"
+                            btnColor="light"
+                            class="btn-group"
+                            [tableActions]="expandClusterActions">
+          </cd-table-actions>
         </div>
         <cd-host-details cdTableDetail
                          [permissions]="permissions"
index e04269aa67c49ddf8e6418b0781d10cad7342d8b..fef729de58a0ef622c76623390e11d58ebb43cbb 100644 (file)
@@ -78,12 +78,16 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit
   @Input()
   showGeneralActionsOnly = false;
 
+  @Input()
+  showExpandClusterBtn = true;
+
   permissions: Permissions;
   columns: Array<CdTableColumn> = [];
   hosts: Array<object> = [];
   isLoadingHosts = false;
   cdParams = { fromLink: '/hosts' };
   tableActions: CdTableAction[];
+  expandClusterActions: CdTableAction[];
   selection = new CdTableSelection();
   modalRef: NgbModalRef;
   isExecuting = false;
@@ -125,6 +129,16 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit
   ) {
     super();
     this.permissions = this.authStorageService.getPermissions();
+    this.expandClusterActions = [
+      {
+        name: this.actionLabels.EXPAND_CLUSTER,
+        permission: 'create',
+        icon: Icons.expand,
+        routerLink: '/expand-cluster',
+        disable: (selection: CdTableSelection) => this.getDisable('add', selection),
+        visible: () => this.showExpandClusterBtn
+      }
+    ];
     this.tableActions = [
       {
         name: this.actionLabels.ADD,
index 725fc953fbb6c6d1cbe25f048cd37b9cdb2242a1..162a429f690d4a34b4715a27129b314e5250c6d4 100644 (file)
@@ -237,6 +237,7 @@ describe('OsdFormComponent', () => {
 
     describe('without data devices selected', () => {
       it('should disable preview button', () => {
+        component.simpleDeployment = false;
         expectPreviewButton(false);
       });
 
index 00a162dac1e2f0b3e6f064dbd53d6a3b49c6904a..16b223b9cbc067334276e8552da6b713dce39bac 100644 (file)
@@ -1,4 +1,12 @@
-import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core';
+import {
+  Component,
+  EventEmitter,
+  Input,
+  OnDestroy,
+  OnInit,
+  Output,
+  ViewChild
+} from '@angular/core';
 import { UntypedFormControl } from '@angular/forms';
 import { Router } from '@angular/router';
 
@@ -34,7 +42,7 @@ import { OsdFeature } from './osd-feature.interface';
   templateUrl: './osd-form.component.html',
   styleUrls: ['./osd-form.component.scss']
 })
-export class OsdFormComponent extends CdForm implements OnInit {
+export class OsdFormComponent extends CdForm implements OnInit, OnDestroy {
   @ViewChild('dataDeviceSelectionGroups')
   dataDeviceSelectionGroups: OsdDevicesSelectionGroupsComponent;
 
@@ -121,12 +129,23 @@ export class OsdFormComponent extends CdForm implements OnInit {
 
     this.osdService.getDeploymentOptions().subscribe((options) => {
       this.deploymentOptions = options;
-      this.form.get('deploymentOption').setValue(this.deploymentOptions?.recommended_option);
+      if (!this.osdService.selectedFormValues) {
+        this.form.get('deploymentOption').setValue(this.deploymentOptions?.recommended_option);
+      }
 
       if (this.deploymentOptions?.recommended_option) {
         this.enableFeatures();
       }
     });
+
+    // restoring form value on back/next
+    if (this.osdService.selectedFormValues) {
+      this.form = _.cloneDeep(this.osdService.selectedFormValues);
+      this.form
+        .get('deploymentOption')
+        .setValue(this.osdService.selectedFormValues.value?.deploymentOption);
+    }
+    this.simpleDeployment = this.osdService.isDeployementModeSimple;
     this.form.get('walSlots').valueChanges.subscribe((value) => this.setSlots('wal', value));
     this.form.get('dbSlots').valueChanges.subscribe((value) => this.setSlots('db', value));
     _.each(this.features, (feature) => {
@@ -283,4 +302,9 @@ export class OsdFormComponent extends CdForm implements OnInit {
       this.previewButtonPanel.submitButton.loading = false;
     }
   }
+
+  ngOnDestroy() {
+    this.osdService.selectedFormValues = _.cloneDeep(this.form);
+    this.osdService.isDeployementModeSimple = this.dataDeviceSelectionGroups?.devices?.length === 0;
+  }
 }
index fc02e9bdeeefbad495ddd56826f61b5b30f99f29..3b9e62c48299846ea49d546eadcc0a50bdd1df4d 100644 (file)
@@ -53,6 +53,8 @@ describe('LoginComponent', () => {
     component.login();
 
     expect(routerNavigateSpy).toHaveBeenCalledTimes(1);
-    expect(routerNavigateSpy).toHaveBeenCalledWith(['/expand-cluster']);
+    expect(routerNavigateSpy).toHaveBeenCalledWith(['/expand-cluster'], {
+      queryParams: { welcome: true }
+    });
   });
 });
index 57039c0f6d0c40cf9a11a5f76e3401c2bf8975f1..8bfda90c9e71be184b712a6ecbc78c75b4dc2204 100644 (file)
@@ -71,7 +71,11 @@ export class LoginComponent implements OnInit {
       if (!this.postInstalled && this.route.snapshot.queryParams['returnUrl'] === '/dashboard') {
         url = '/expand-cluster';
       }
-      this.router.navigate([url]);
+      if (url == '/expand-cluster') {
+        this.router.navigate([url], { queryParams: { welcome: true } });
+      } else {
+        this.router.navigate([url]);
+      }
     });
   }
 }
index 34461bf6314930ba2b98b9e43ae3c02320055675..f2ed4d7cc9e764e58447cee78621f268286be4ba 100644 (file)
@@ -11,6 +11,7 @@ import { DeploymentOptions } from '../models/osd-deployment-options';
 import { OsdSettings } from '../models/osd-settings';
 import { SmartDataResponseV1 } from '../models/smart';
 import { DeviceService } from '../services/device.service';
+import { CdFormGroup } from '../forms/cd-form-group';
 
 @Injectable({
   providedIn: 'root'
@@ -20,6 +21,8 @@ export class OsdService {
   private uiPath = 'ui-api/osd';
 
   osdDevices: InventoryDeviceType[] = [];
+  selectedFormValues: CdFormGroup;
+  isDeployementModeSimple: boolean = true;
 
   osdRecvSpeedModalPriorities = {
     KNOWN_PRIORITIES: [
index 185c778bc1bdfd15a346116cb5371c15541c9ad5..24915507fd9aea2e6bbf291e567adf87a4cfef7b 100644 (file)
@@ -148,6 +148,7 @@ export class ActionLabelsI18n {
   DISCONNECT: string;
   RECONNECT: string;
   AUTHORIZE: string;
+  EXPAND_CLUSTER: string;
 
   constructor() {
     /* Create a new item */
@@ -234,6 +235,7 @@ export class ActionLabelsI18n {
     this.CONNECT = $localize`Connect`;
     this.DISCONNECT = $localize`Disconnect`;
     this.RECONNECT = $localize`Reconnect`;
+    this.EXPAND_CLUSTER = $localize`Expand Cluster`;
   }
 }
 
index be454076b862142df628a4d189fe03b3380ff712..8f90a51cf86735a8939dcb74006e8416b0673a88 100644 (file)
@@ -27,7 +27,7 @@ export enum Icons {
   right = 'fa fa-arrow-right', // Mark in
   down = 'fa fa-arrow-down', // Mark Down
   erase = 'fa fa-eraser', // Purge  color: bd.$white;
-
+  expand = 'fa fa-expand', // Expand cluster
   user = 'fa fa-user', // User, Initiators
   users = 'fa fa-users', // Users, Groups
   share = 'fa fa-share-alt', // share