]> git.apps.os.sepia.ceph.com Git - ceph-ci.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>
Fri, 19 Jun 2020 07:49:31 +0000 (09:49 +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>
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 cf26fc381a1c0974ac85b8958ab3f0e3f2324f27..d271b21b0dafff4735678eeb28eae557f570b708 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 111f3c68fb5314549c926da138c10a348f3e67a8..4214fa71411725ce536292f45c88b64f0ef8c2f6 100644 (file)
@@ -1,6 +1,6 @@
 <ngb-alert class="no-margin-bottom"
            type="{{ alertType }}"
-           *ngIf="expirationDays != null && expirationDays <= pwdExpirationSettings.pwdExpirationWarning1"
+           *ngIf="displayNotification"
            (close)="close($event)">
   <div *ngIf="expirationDays === 0"
        i18n>Your password will expire in <strong>less than 1</strong> day. Click
index c5392e3aaa919fe2925b25472b21b8dee4709eed..83e1664643bd386874fa615b62e302a6e18b30e0 100644 (file)
@@ -13,6 +13,7 @@ export class PwdExpirationNotificationComponent implements OnInit, OnDestroy {
   alertType: string;
   expirationDays: number;
   pwdExpirationSettings: CdPwdExpirationSettings;
+  displayNotification = false;
 
   constructor(
     private settingsService: SettingsService,
@@ -30,7 +31,7 @@ export class PwdExpirationNotificationComponent implements OnInit, OnDestroy {
         } else {
           this.alertType = 'warning';
         }
-
+        this.displayNotification = true;
         this.authStorageService.isPwdDisplayedSource.next(true);
       }
     });
@@ -48,5 +49,6 @@ export class PwdExpirationNotificationComponent implements OnInit, OnDestroy {
 
   close() {
     this.authStorageService.isPwdDisplayedSource.next(false);
+    this.displayNotification = false;
   }
 }
index 98a6fcf69f7087630a5a1abe874068e084ca54d7..fa62ef90c08389ad3aa74117761b85d660439fa0 100644 (file)
@@ -121,7 +121,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;