]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: support >1 top notification panels
authorTatjana Dehler <tdehler@suse.com>
Fri, 15 May 2020 13:54:04 +0000 (15:54 +0200)
committerTatjana Dehler <tdehler@suse.com>
Tue, 11 Aug 2020 13:59:47 +0000 (15:59 +0200)
Update navigation component in order to show more than
one notification panel on top of the page.

Signed-off-by: Tatjana Dehler <tdehler@suse.com>
(cherry picked from commit 455dca6bbe0c26ad682be394335a68399d17c486)

Conflicts:
src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html
The alert component has been migrated from ngx-bootstrap to ng-boostrap in master: https://github.com/ceph/ceph/pull/35297

src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts
src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts
src/pybind/mgr/dashboard/frontend/src/styles/defaults.scss

index 0000dd3337edefed0ed907a6e1f896bdf107ef7c..9c0d8f09d733416476f6242d608f0ecc563ce1de 100644 (file)
@@ -10,7 +10,7 @@
     border-top: 4px solid $color-nav-top-bar;
 
     &.isPwdDisplayed {
-      top: $pwd-exp-height;
+      top: $top-notification-height;
     }
 
     .navbar-brand,
@@ -255,22 +255,25 @@ $sidebar-width: 200px;
 }
 
 /* ---------------------------------------------------
-    isPwdDisplayed
+    topNotification settings
 --------------------------------------------------- */
-:host.isPwdDisplayed {
-  .cd-navbar-top .cd-navbar-brand {
-    top: $pwd-exp-height;
-  }
 
-  #sidebar {
-    top: $navbar-height + $pwd-exp-height;
-  }
+@for $i from 1 through 2 {
+  :host.top-notification-#{$i} {
+    .cd-navbar-top .cd-navbar-brand {
+      top: $top-notification-height * $i;
+    }
 
-  #content {
-    top: $navbar-height + $pwd-exp-height;
-  }
+    #sidebar {
+      top: $navbar-height + $top-notification-height * $i;
+    }
+
+    #content {
+      top: $navbar-height + $top-notification-height * $i;
+    }
 
-  cd-notifications-sidebar {
-    top: $navbar-height + $pwd-exp-height + 10px;
+    cd-notifications-sidebar {
+      top: $navbar-height + $top-notification-height * $i + 10px;
+    }
   }
 }
index 1302f7a3abee6f7c864c305866d8a6a5b0f1d054..0f7764e05d9d85b86dea02ffad842e510ba9d038 100644 (file)
@@ -180,4 +180,56 @@ describe('NavigationComponent', () => {
       });
     }
   });
+
+  describe('showTopNotification', () => {
+    const notification1 = 'notificationName1';
+    const notification2 = 'notificationName2';
+
+    beforeEach(() => {
+      component.notifications = [];
+    });
+
+    it('should show notification', () => {
+      component.showTopNotification(notification1, true);
+      expect(component.notifications.includes(notification1)).toBeTruthy();
+      expect(component.notifications.length).toBe(1);
+    });
+
+    it('should not add a second notification if it is already shown', () => {
+      component.showTopNotification(notification1, true);
+      component.showTopNotification(notification1, true);
+      expect(component.notifications.includes(notification1)).toBeTruthy();
+      expect(component.notifications.length).toBe(1);
+    });
+
+    it('should add a second notification if the first one is different', () => {
+      component.showTopNotification(notification1, true);
+      component.showTopNotification(notification2, true);
+      expect(component.notifications.includes(notification1)).toBeTruthy();
+      expect(component.notifications.includes(notification2)).toBeTruthy();
+      expect(component.notifications.length).toBe(2);
+    });
+
+    it('should hide an active notification', () => {
+      component.showTopNotification(notification1, true);
+      expect(component.notifications.includes(notification1)).toBeTruthy();
+      expect(component.notifications.length).toBe(1);
+      component.showTopNotification(notification1, false);
+      expect(component.notifications.length).toBe(0);
+    });
+
+    it('should not fail if it tries to hide an inactive notification', () => {
+      expect(() => component.showTopNotification(notification1, false)).not.toThrow();
+      expect(component.notifications.length).toBe(0);
+    });
+
+    it('should keep other notifications if it hides one', () => {
+      component.showTopNotification(notification1, true);
+      component.showTopNotification(notification2, true);
+      expect(component.notifications.length).toBe(2);
+      component.showTopNotification(notification2, false);
+      expect(component.notifications.length).toBe(1);
+      expect(component.notifications.includes(notification1)).toBeTruthy();
+    });
+  });
 });
index c184d0cda5fcdad9712570276ffb7817a1530430..ce04147754015fa07f29179157a688413ad56c39 100644 (file)
@@ -18,7 +18,10 @@ import { SummaryService } from '../../../shared/services/summary.service';
   styleUrls: ['./navigation.component.scss']
 })
 export class NavigationComponent implements OnInit, OnDestroy {
-  @HostBinding('class.isPwdDisplayed') isPwdDisplayed = false;
+  notifications: string[] = [];
+  @HostBinding('class') get class(): string {
+    return 'top-notification-' + this.notifications.length;
+  }
 
   permissions: Permissions;
   enabledFeature$: FeatureTogglesMap$;
@@ -50,9 +53,14 @@ export class NavigationComponent implements OnInit, OnDestroy {
         this.summaryData = summary;
       })
     );
+    /*
+     Note: If you're going to add more top notifications please do not forget to increase
+     the number of generated css-classes in section topNotification settings in the scss
+     file.
+     */
     this.subs.add(
       this.authStorageService.isPwdDisplayed$.subscribe((isDisplayed) => {
-        this.isPwdDisplayed = isDisplayed;
+        this.showTopNotification('isPwdDisplayed', isDisplayed);
       })
     );
   }
@@ -80,4 +88,17 @@ export class NavigationComponent implements OnInit, OnDestroy {
       this.displayedSubMenu = menu;
     }
   }
+
+  showTopNotification(name: string, isDisplayed: boolean) {
+    if (isDisplayed) {
+      if (!this.notifications.includes(name)) {
+        this.notifications.push(name);
+      }
+    } else {
+      const index = this.notifications.indexOf(name);
+      if (index >= 0) {
+        this.notifications.splice(index, 1);
+      }
+    }
+  }
 }
index 36615164bd62f1c2e40393f5babc1cba6e664239..5a43e92e1dce42477e1c61989edeebda1178e9f4 100644 (file)
@@ -1,6 +1,6 @@
 <alert class="no-margin-bottom"
        type="{{ alertType }}"
-       *ngIf="expirationDays != null && expirationDays <= pwdExpirationSettings.pwdExpirationWarning1"
+       *ngIf="displayNotification"
        [dismissible]="true"
        (onClose)="close($event)">
   <div *ngIf="expirationDays === 0"
index 0955f52e93657ed8b61bbe33a05b439052542752..cfa8e145d4a22c79e619a8eb4c31fc7b32149580 100644 (file)
@@ -13,6 +13,7 @@ export class PwdExpirationNotificationComponent implements OnInit {
   alertType: string;
   expirationDays: number;
   pwdExpirationSettings: CdPwdExpirationSettings;
+  displayNotification = false;
 
   constructor(
     private settingsService: SettingsService,
@@ -30,7 +31,7 @@ export class PwdExpirationNotificationComponent implements OnInit {
         } else {
           this.alertType = 'warning';
         }
-
+        this.displayNotification = true;
         this.authStorageService.isPwdDisplayedSource.next(true);
       }
     });
@@ -44,5 +45,6 @@ export class PwdExpirationNotificationComponent implements OnInit {
 
   close() {
     this.authStorageService.isPwdDisplayedSource.next(false);
+    this.displayNotification = false;
   }
 }
index afbb031ceb9ae6fae57ca51639f7cb3cd1a3590d..1b4382ca1a0506d4f4d924e585b978c1a6b9eb46 100644 (file)
@@ -116,7 +116,7 @@ $color-nav-active-link-bg: $color-primary !default;
 $color-nav-border-top-collapse: $color-white-gray !default;
 
 $navbar-height: 43px;
-$pwd-exp-height: 37.6px;
+$top-notification-height: 37.6px;
 
 /*Helper*/
 $color-helper-bg: $color-primary !default;