From 455dca6bbe0c26ad682be394335a68399d17c486 Mon Sep 17 00:00:00 2001 From: Tatjana Dehler Date: Fri, 15 May 2020 15:54:04 +0200 Subject: [PATCH] mgr/dashboard: support >1 top notification panels Update navigation component in order to show more than one notification panel on top of the page. Signed-off-by: Tatjana Dehler --- .../navigation/navigation.component.scss | 31 ++++++----- .../navigation/navigation.component.spec.ts | 52 +++++++++++++++++++ .../navigation/navigation.component.ts | 25 ++++++++- ...pwd-expiration-notification.component.html | 2 +- .../pwd-expiration-notification.component.ts | 4 +- .../frontend/src/styles/defaults.scss | 2 +- 6 files changed, 97 insertions(+), 19 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss index cf26fc381a1..d271b21b0da 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.scss @@ -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; + } } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts index 1302f7a3abe..0f7764e05d9 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.spec.ts @@ -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(); + }); + }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts index c184d0cda5f..ce041477540 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.ts @@ -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); + } + } + } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html index 111f3c68fb5..4214fa71411 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.html @@ -1,6 +1,6 @@
Your password will expire in less than 1 day. Click diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts index c5392e3aaa9..83e1664643b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/pwd-expiration-notification/pwd-expiration-notification.component.ts @@ -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; } } diff --git a/src/pybind/mgr/dashboard/frontend/src/styles/defaults.scss b/src/pybind/mgr/dashboard/frontend/src/styles/defaults.scss index 98a6fcf69f7..fa62ef90c08 100644 --- a/src/pybind/mgr/dashboard/frontend/src/styles/defaults.scss +++ b/src/pybind/mgr/dashboard/frontend/src/styles/defaults.scss @@ -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; -- 2.39.5