diff options
Diffstat (limited to 'src/app/components/layout')
8 files changed, 666 insertions, 0 deletions
diff --git a/src/app/components/layout/header/header/header.component.css b/src/app/components/layout/header/header/header.component.css new file mode 100644 index 0000000..21de90f --- /dev/null +++ b/src/app/components/layout/header/header/header.component.css @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +.navbar { + background-color: #e7e6e6; +} + +.bi-list { + font-size: 1.5rem; +} + +.dropdown-menu { + border-radius: 10px; + border: 0.5px solid #b2b2b2; + text-align: center; + box-shadow: 3px 3px 20px lightslategray; +} + +#dropdown-user, +#dropdown-settings { + text-align: left; +} + +#dropdownMenu:hover, +#dropdownMenu:focus { + background-color: #e7e6e6; +} + +.dropdown-divider { + border-color: #b2b2b2; +} + +.navbar-collapse.collapse.in { + display: inline-block; +} + +.dropdown-toggle::after { + content: initial; +} + +.navbar-toggler { + color: black; +} + +.sidebar-toggler { + background-color: transparent; + border-style: none; +} + +.btn-account { + color: black; + background-color: transparent; + border-style: none; + font-size: 21px; + line-height: 1.225; +} + +.btn:hover { + background-color: #e7e6e6; +} + +/* Make ONAP logo as large as the Telekom one */ +.brand-image { + height: 36px; +} + +.bi.bi-person-fill, +.bi.bi-caret-down-fill { + color: black; +} + +/* Add a clearly visible outline while tabbing */ +:focus-visible { + box-shadow: 0 0 0 2px black; +} +dl > * { + text-align: left; +} + +hr { + margin-top: 1.4rem; + margin-bottom: 1.4rem; + border: 0; + border-top: 1px solid; +} + +.btn { + white-space: nowrap; + display: block; +} + +.btn:hover { + color: var(--black); +} + +.btn-sm, +.btn-group-sm > .btn { + padding: 0.4rem 1.5rem 0.476rem; +} diff --git a/src/app/components/layout/header/header/header.component.html b/src/app/components/layout/header/header/header.component.html new file mode 100644 index 0000000..8e23ffd --- /dev/null +++ b/src/app/components/layout/header/header/header.component.html @@ -0,0 +1,142 @@ +<!-- + ~ Copyright (c) 2022. Deutsche Telekom AG + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + ~ SPDX-License-Identifier: Apache-2.0 + --> + +<nav id="brand-bar" class="navbar navbar-light navbar-expand pl-2"> + <button + type="button" + id="sidebarCollapse" + class="sidebar-toggler" + (click)="toggleSidenav()" + [attr.aria-label]="'layout.header.sidebarToggler' | translate" + > + <i class="bi bi-list" aria-hidden="true"></i> + </button> + + <!-- Logo as Home Button --> + <a class="ml-3" [routerLink]="['/']"> + <img + class="brand-image pl-0" + id="img-logo" + src="assets/images/onap-logo.png" + alt="{{ 'layout.header.logo.onap' | translate }}" + /> + </a> + + <div class="d-flex ml-auto align-items-baseline"> + <button + class="btn btn-invisible p-2 pointer" + [attr.accesskey]="ACCESS_KEY.SHORTCUT_0" + (click)="openCanvas(content)" + [attr.aria-label]="'Help'" + [ngbTooltip]="'Help'" + > + <i aria-hidden="true" class="bi bi-question-circle black"></i> + </button> + <button + *ngIf="!isFullScreen" + class="btn btn-invisible pointer p-2 qa_btn_open_fullscreen" + [attr.aria-label]="'layout.header.button.openFullscreen' | translate" + [ngbTooltip]="'Full screen'" + (click)="openFullscreen()" + > + <i aria-hidden="true" class="bi bi-arrows-fullscreen black"></i> + </button> + <button + *ngIf="isFullScreen" + class="btn btn-invisible pointer p-2 qa_btn_cls_fullscreen" + [attr.aria-label]="'layout.header.button.closeFullscreen' | translate" + [ngbTooltip]="'Exit full screen'" + (click)="closeFullscreen()" + > + <i aria-hidden="true" class="bi bi-fullscreen-exit black"></i> + </button> + </div> + + <!-- Dropdown menu --> + <div ngbDropdown #userAccountDropdown="ngbDropdown" display="dynamic"> + <button + ngbDropdownToggle + id="dropdownMenu" + class="btn btn-account px-3 tab-focus" + [attr.aria-label]="'layout.header.button.useraccount' | translate" + aria-haspopup="true" + > + <i class="bi bi-person-fill" aria-hidden="true"></i> + <i class="bi bi-caret-down-fill" aria-hidden="true"></i> + </button> + <div class="dropdown-menu-right px-4" ngbDropdownMenu aria-labelledby="dropdownMenu" + style="z-index: 9999; min-width: 380px"> + <div class="d-flex justify-content-between align-items-center"> + <div> + <i aria-hidden="true" class="bi bi-person"></i> + {{ profile }} + </div> + <button + class="btn btn-sm btn-primary font-weight-bold" + (click)="userAccountDropdown.close(); logOut()" + [attr.aria-label]="'layout.header.button.logout' | translate" + > + {{ 'layout.header.button.logout' | translate }} + </button> + </div> + <hr /> + <dl> + <dt>{{ 'layout.header.info.name' | translate }}</dt> + <dd>{{ profile }}</dd> + <dt>{{ 'layout.header.info.mail' | translate }}</dt> + <dd>{{ email }}</dd> + </dl> + <hr /> + <button + type="button" + class="btn btn-sm btn-outline-secondary" + placement="top" + container="body" + triggers="click:blur" + [ngbTooltip]="'userAdministration.form.title.changePasswordTooltip' | translate" + > + {{ 'userAdministration.form.title.changePassword' | translate }} + </button> + </div> + </div> +</nav> + +<ng-template #content let-offcanvas> + <div class="offcanvas-header"> + <div class="d-flex"> + <h3 class="mb-0 mr-1">{{ 'layout.header.shortcuts.heading' | translate }}</h3> + </div> + <button + type="button" + class="align-self-center btn-close" + [attr.aria-label]="'common.buttons.close' | translate" + (click)="offcanvas.dismiss(content)" + ></button> + </div> + <div class="offcanvas-body"> + <p class="border-bottom pb-2" *ngFor="let shortcut of shortcuts | keyvalue"> + {{ shortcut.key }} - {{ shortcut.value }} + </p> + <div class="text-muted small"> + <p>{{ 'layout.header.shortcuts.helpText' | translate }}</p> + <div [innerHTML]="'layout.header.shortcuts.helpBrowser1' | translate"></div> + <div [innerHTML]="'layout.header.shortcuts.helpBrowser2' | translate"></div> + <div [innerHTML]="'layout.header.shortcuts.helpBrowser3' | translate"></div> + </div> + </div> +</ng-template> diff --git a/src/app/components/layout/header/header/header.component.spec.ts b/src/app/components/layout/header/header/header.component.spec.ts new file mode 100644 index 0000000..cb40e73 --- /dev/null +++ b/src/app/components/layout/header/header/header.component.spec.ts @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HeaderComponent } from './header.component'; + +describe('HeaderComponent', () => { + let component: HeaderComponent; + let fixture: ComponentFixture<HeaderComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [HeaderComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/layout/header/header/header.component.ts b/src/app/components/layout/header/header/header.component.ts new file mode 100644 index 0000000..f5c1a1c --- /dev/null +++ b/src/app/components/layout/header/header/header.component.ts @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +import { + Component, + Output, + EventEmitter, + OnInit, + HostListener, + ElementRef, + ViewChild, + TemplateRef, +} from '@angular/core'; +import { OAuthService } from 'angular-oauth2-oidc'; +import { FullscreenService } from 'src/app/services/fullscreen.service'; +import { environment } from 'src/environments/environment'; +import { KeyboardShortcuts, ShortcutService } from 'src/app/services/shortcut.service'; +import { NgbOffcanvas } from '@ng-bootstrap/ng-bootstrap'; + +@Component({ + selector: 'app-header', + templateUrl: './header.component.html', + styleUrls: ['./header.component.css'], +}) +export class HeaderComponent implements OnInit { +@Output() collapse = new EventEmitter<void>() + + /** + * + * @param {OAuthService} oauthService + */ + isOnapTheme = false; + switchToMainContent: string = ''; + isFullScreen = false; + changePasswordUrl = `${environment.keycloakEditProfile}/password`; + shortcuts: Map<KeyboardShortcuts,string> = this.shortcutService.getShortcuts(); + + public ACCESS_KEY = KeyboardShortcuts; + @ViewChild('myNavElement') myNavElement!: ElementRef; + + constructor( + private readonly fullscreenService: FullscreenService, + private readonly oauthService: OAuthService, + private offcanvasService: NgbOffcanvas, + private shortcutService: ShortcutService + ) {} + ngOnInit(): void { + this.checkScreenMode(); + } + + @HostListener('document:fullscreenchange', ['$event']) + @HostListener('document:webkitfullscreenchange', ['$event']) + @HostListener('document:mozfullscreenchange', ['$event']) + @HostListener('document:MSFullscreenChange', ['$event']) + private checkScreenMode() { + this.isFullScreen = !!document.fullscreenElement; + } + + public openFullscreen() { + this.fullscreenService.enter(); + } + public closeFullscreen() { + this.fullscreenService.leave(); + } + + public logIn() { + this.oauthService.initCodeFlow(); + } + + public logOut() { + this.oauthService.logOut(); + } + + get profile() { + const claims = Object(this.oauthService.getIdentityClaims()); + return claims.given_name ? claims.given_name : 'no Name'; + } + + get email() { + const claims = Object(this.oauthService.getIdentityClaims()); + return claims.email ? claims.email : 'no Email'; + } + + public toggleSidenav() { + this.collapse.emit(); + } + + + public openCanvas(content: TemplateRef<any>) { + const isCanvasOpened = this.offcanvasService.hasOpenOffcanvas(); + if (isCanvasOpened) { + this.offcanvasService.dismiss(); + } else { + this.offcanvasService.open(content, { ariaLabelledBy: 'Keyboard shortcuts', position: 'end' }); + } + } +} diff --git a/src/app/components/layout/sidemenu/sidemenu.component.css b/src/app/components/layout/sidemenu/sidemenu.component.css new file mode 100644 index 0000000..23831b7 --- /dev/null +++ b/src/app/components/layout/sidemenu/sidemenu.component.css @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +/* Sidebar container with nav menu */ +#sidebar-container { + margin-right: -1px; + flex: 0 0 230px; + border-right-style: solid; + border-right-width: 1px; + border-right-color: #b2b2b2; +} + +/* Menu item*/ +.nav a { + height: 50px; + color: black; +} + +/* Li elements from sidemenu. Thanks to padding is :focus pseudo-class visible for keyboard users*/ +.nav li { + padding: 2px; +} + +/* Separators */ +.sidebar-separator-title { + height: 2em; +} + +/* Sidebar sizes when collapsed*/ +.sidebar-collapsed { + min-width: 60px !important; + max-width: 63px !important; + height: auto; +} + +/* Sidebar sizes when expanded*/ +.sidebar-expanded { + min-width: 250px; + max-width: 250px; + height: 100%; + display: block; + border-right-style: solid; + border-right-width: 1px; + border-right-color: #c5c5c5; +} + +/* Hide list item and grouping item title if container sidebar is collapsed */ +.sidebar-collapsed a.nav-link span, +.sidebar-collapsed li.sidebar-separator-title small { + display: none !important; +} + +/* Hide grouping item icon if container sidebar is collapsed */ +.sidebar-expanded ul li.sidebar-separator-title i, +.sidebar-expanded ul li.sidebar-separator-title img { + display: none !important; +} + +/* Show grouping item icon if container sidebar is collapsed */ +.sidebar-collapsed ul li.sidebar-separator-title i, +.sidebar-collapsed ul li.sidebar-separator-title img { + display: inline-block; +} + +/* All list items */ +.nav-link { + border-style: none; + display: block !important; + padding: 0.75rem 1rem; +} + +ul { + list-style-type: none; +} + +.active-menu-item { + background-color: var(--active-gray); + color: black; + border-top-left-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; + border-left: 2px solid var(--primary) !important; +} + +.nav.inner li { + border: none; +} + +.portal-version-title, +.portal-version-number { + font-size: 13px; +} + +img { + width: 18px; + height: 19px; + vertical-align: -0.125em; +} diff --git a/src/app/components/layout/sidemenu/sidemenu.component.html b/src/app/components/layout/sidemenu/sidemenu.component.html new file mode 100644 index 0000000..fd97c50 --- /dev/null +++ b/src/app/components/layout/sidemenu/sidemenu.component.html @@ -0,0 +1,51 @@ +<!-- + ~ Copyright (c) 2022. Deutsche Telekom AG + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + ~ + ~ SPDX-License-Identifier: Apache-2.0 + --> + + +<nav + [class.sidebar-collapsed]="isSidebarCollapsed" + id="sidebar-container" + class="sidebar-expanded overflow-auto d-flex flex-column justify-content-between" + [attr.aria-label]="'layout.menu.mainMenu' | translate" +> + <ul class="nav flex-column flex-nowrap" [attr.aria-label]="'layout.menu.menuItems' | translate"> + <li class="nav-item"> + <a #test [attr.accesskey]='ACCESS_KEY.SHORTCUT_6' class="nav-link" routerLinkActive="active-menu-item" [routerLink]="['/dashboard']"> + <i class="bi bi-house-door mr-4" aria-hidden="true"></i> + <span class="d-sm-inline qa_menu_home">{{ 'layout.menu.items.dashboard' | translate }}</span></a + > + </li> + <li class="nav-item"> + <a class="nav-link" routerLinkActive="active-menu-item" [routerLink]="['/app-starter']"> + <i class="bi bi-grid mr-4" aria-hidden="true"></i> + <span class="d-sm-inline qa_menu_app_starter">{{ 'layout.menu.items.appStarter' | translate }}</span></a + > + </li> + + <li class="nav-item" [appHasPermissions]="'users.administration.list'"> + <a class="nav-link" routerLinkActive="active-menu-item" routerLink="/user-administration"> + <i class="bi bi-people mr-4" aria-hidden="true"></i> + <span class="d-sm-inline qa_menu_users">{{ 'layout.menu.items.users' | translate }}</span></a + > + </li> + </ul> + <div [ngClass]="isSidebarCollapsed ? 'flex-column' : 'flex-row'" class="d-flex justify-content-center text-center"> + <h5 class="portal-version-title mr-1" id="portal-version">Portal Version:</h5> + <span class="portal-version-number" aria-labelledby="portal-version" (click)='test.blur()'>{{versionNumber}}</span> + </div> +</nav> diff --git a/src/app/components/layout/sidemenu/sidemenu.component.spec.ts b/src/app/components/layout/sidemenu/sidemenu.component.spec.ts new file mode 100644 index 0000000..1067c49 --- /dev/null +++ b/src/app/components/layout/sidemenu/sidemenu.component.spec.ts @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + + +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SidemenuComponent } from './sidemenu.component'; + +describe('SidemenuComponent', () => { + let component: SidemenuComponent; + let fixture: ComponentFixture<SidemenuComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [SidemenuComponent], + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SidemenuComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/layout/sidemenu/sidemenu.component.ts b/src/app/components/layout/sidemenu/sidemenu.component.ts new file mode 100644 index 0000000..1f5c123 --- /dev/null +++ b/src/app/components/layout/sidemenu/sidemenu.component.ts @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022. Deutsche Telekom AG + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +import { Component, Injectable, Input } from '@angular/core'; +import { environment } from 'src/environments/environment'; +import VersionJson from 'src/assets/version.json'; +import { KeyboardShortcuts } from '../../../services/shortcut.service'; + +@Injectable({ + providedIn: 'root', +}) +@Component({ + selector: 'app-sidemenu', + templateUrl: './sidemenu.component.html', + styleUrls: ['./sidemenu.component.css'], +}) +export class SidemenuComponent { + versionNumber: string; + + @Input() isSidebarCollapsed = false; + + public ACCESS_KEY = KeyboardShortcuts; + public keycloakEditProfile = environment.keycloakEditProfile; + public isKpiDashboardSubMenuCollapsed = false; + + constructor() { + this.versionNumber = VersionJson.number; + } + collapsed() { + this.isKpiDashboardSubMenuCollapsed = !this.isKpiDashboardSubMenuCollapsed; + } +} |