aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/components')
-rw-r--r--src/app/components/layout/header/header/header.component.css114
-rw-r--r--src/app/components/layout/header/header/header.component.html142
-rw-r--r--src/app/components/layout/header/header/header.component.spec.ts43
-rw-r--r--src/app/components/layout/header/header/header.component.ts113
-rw-r--r--src/app/components/layout/sidemenu/sidemenu.component.css113
-rw-r--r--src/app/components/layout/sidemenu/sidemenu.component.html51
-rw-r--r--src/app/components/layout/sidemenu/sidemenu.component.spec.ts43
-rw-r--r--src/app/components/layout/sidemenu/sidemenu.component.ts47
-rw-r--r--src/app/components/modal/modal-content.html30
-rw-r--r--src/app/components/modal/modal-content.ts32
-rw-r--r--src/app/components/modal/modal.service.ts38
-rw-r--r--src/app/components/page-not-found/page-not-found.css36
-rw-r--r--src/app/components/page-not-found/page-not-found.html29
-rw-r--r--src/app/components/page-not-found/page-not-found.ts27
-rw-r--r--src/app/components/shared/breadcrumb-item/breadcrumb-item.component.html22
-rw-r--r--src/app/components/shared/breadcrumb-item/breadcrumb-item.component.ts29
-rw-r--r--src/app/components/shared/breadcrumb/breadcrumb.component.html26
-rw-r--r--src/app/components/shared/breadcrumb/breadcrumb.component.ts30
-rw-r--r--src/app/components/shared/confirmation-modal/confirmation-modal.component.html35
-rw-r--r--src/app/components/shared/confirmation-modal/confirmation-modal.component.spec.ts19
-rw-r--r--src/app/components/shared/confirmation-modal/confirmation-modal.component.ts39
-rw-r--r--src/app/components/shared/loading-spinner/loading-spinner.component.html21
-rw-r--r--src/app/components/shared/loading-spinner/loading-spinner.component.ts26
-rw-r--r--src/app/components/shared/pagination/pagination.component.css23
-rw-r--r--src/app/components/shared/pagination/pagination.component.html48
-rw-r--r--src/app/components/shared/pagination/pagination.component.spec.ts43
-rw-r--r--src/app/components/shared/pagination/pagination.component.ts88
-rw-r--r--src/app/components/shared/status-page/status-page.component.css19
-rw-r--r--src/app/components/shared/status-page/status-page.component.html23
-rw-r--r--src/app/components/shared/status-page/status-page.component.spec.ts44
-rw-r--r--src/app/components/shared/status-page/status-page.component.ts37
-rw-r--r--src/app/components/shared/table-skeleton/table-skeleton.component.css37
-rw-r--r--src/app/components/shared/table-skeleton/table-skeleton.component.html31
-rw-r--r--src/app/components/shared/table-skeleton/table-skeleton.component.ts29
34 files changed, 1527 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;
+ }
+}
diff --git a/src/app/components/modal/modal-content.html b/src/app/components/modal/modal-content.html
new file mode 100644
index 0000000..ec3b6c4
--- /dev/null
+++ b/src/app/components/modal/modal-content.html
@@ -0,0 +1,30 @@
+<!--
+ ~ 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
+ -->
+
+
+<div class="modal-body m-3" style="text-align: justify">
+ <h4 class="modal-title">{{'modal.error.accessDenied' | translate}}</h4>
+ <p><br />{{'modal.error.accessDenied' | translate}}</p>
+ <details>
+ <summary>{{'modal.error.details' | translate}}</summary>
+ <p>{{message}}</p>
+ </details>
+ <div style="text-align: right">
+ <button class="btn btn-primary" (click)="oauthService.logOut()">Logout</button>
+ </div>
+</div>
diff --git a/src/app/components/modal/modal-content.ts b/src/app/components/modal/modal-content.ts
new file mode 100644
index 0000000..01211df
--- /dev/null
+++ b/src/app/components/modal/modal-content.ts
@@ -0,0 +1,32 @@
+/*
+ * 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, Input } from '@angular/core';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { OAuthService } from 'angular-oauth2-oidc';
+
+@Component({
+ selector: 'app-modal-content',
+ templateUrl: './modal-content.html',
+})
+export class ModalContentComponent {
+ @Input() message: any;
+
+ constructor(public activeModal: NgbActiveModal, public oauthService: OAuthService) {}
+}
diff --git a/src/app/components/modal/modal.service.ts b/src/app/components/modal/modal.service.ts
new file mode 100644
index 0000000..083bcb1
--- /dev/null
+++ b/src/app/components/modal/modal.service.ts
@@ -0,0 +1,38 @@
+/*
+ * 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 { Injectable } from '@angular/core';
+import { NgbModal, NgbModalConfig } from '@ng-bootstrap/ng-bootstrap';
+import { ModalContentComponent } from './modal-content';
+
+@Injectable({
+ providedIn: 'root',
+})
+export class ModalService {
+ constructor(private modalService: NgbModal, private modalConfig: NgbModalConfig) {
+ // customize default values of modals used by this component tree
+ modalConfig.backdrop = 'static';
+ modalConfig.keyboard = false;
+ }
+
+ open(message: string) {
+ const modalRef = this.modalService.open(ModalContentComponent,{backdropClass:'backdropClass'});
+ modalRef.componentInstance.message = message;
+ }
+}
diff --git a/src/app/components/page-not-found/page-not-found.css b/src/app/components/page-not-found/page-not-found.css
new file mode 100644
index 0000000..2c10482
--- /dev/null
+++ b/src/app/components/page-not-found/page-not-found.css
@@ -0,0 +1,36 @@
+/*
+ * 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
+ */
+
+
+.wrapper {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-40%, -50%);
+}
+
+.woman-img {
+ height: 350px;
+}
+
+.icon {
+ position: absolute;
+ top: 5px;
+ font-size: 30px;
+ color: var(--primary);
+}
diff --git a/src/app/components/page-not-found/page-not-found.html b/src/app/components/page-not-found/page-not-found.html
new file mode 100644
index 0000000..6ad90c6
--- /dev/null
+++ b/src/app/components/page-not-found/page-not-found.html
@@ -0,0 +1,29 @@
+<!--
+ ~ 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
+ -->
+
+
+<div class="container text-center wrapper">
+ <img
+ class="woman-img mb-5"
+ src="assets/images/icons/standing-woman.svg"
+ alt="{{'pageNotFound.imgAltText' | translate}}"
+ />
+ <i class="bi bi-x-circle-fill icon" aria-hidden="true"></i>
+ <h3 class="mb-3">{{'pageNotFound.text' | translate}}</h3>
+ <button type="button" class="btn btn-primary" routerLink="/dashboard">{{'pageNotFound.button' | translate}}</button>
+</div>
diff --git a/src/app/components/page-not-found/page-not-found.ts b/src/app/components/page-not-found/page-not-found.ts
new file mode 100644
index 0000000..88cdc01
--- /dev/null
+++ b/src/app/components/page-not-found/page-not-found.ts
@@ -0,0 +1,27 @@
+/*
+ * 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 } from '@angular/core';
+
+@Component({
+ selector: 'app-page-not-found',
+ templateUrl: './page-not-found.html',
+ styleUrls: ['./page-not-found.css'],
+})
+export class PageNotFoundComponent {}
diff --git a/src/app/components/shared/breadcrumb-item/breadcrumb-item.component.html b/src/app/components/shared/breadcrumb-item/breadcrumb-item.component.html
new file mode 100644
index 0000000..72d5c79
--- /dev/null
+++ b/src/app/components/shared/breadcrumb-item/breadcrumb-item.component.html
@@ -0,0 +1,22 @@
+<!--
+ ~ 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
+ -->
+
+
+<ng-template>
+ <ng-content></ng-content>
+</ng-template>
diff --git a/src/app/components/shared/breadcrumb-item/breadcrumb-item.component.ts b/src/app/components/shared/breadcrumb-item/breadcrumb-item.component.ts
new file mode 100644
index 0000000..5f74fff
--- /dev/null
+++ b/src/app/components/shared/breadcrumb-item/breadcrumb-item.component.ts
@@ -0,0 +1,29 @@
+/*
+ * 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, TemplateRef, ViewChild } from '@angular/core';
+
+@Component({
+ selector: 'app-breadcrumb-item',
+ templateUrl: './breadcrumb-item.component.html',
+})
+export class BreadcrumbItemComponent {
+ @ViewChild(TemplateRef, { static: true })
+ readonly template!: TemplateRef<any>;
+}
diff --git a/src/app/components/shared/breadcrumb/breadcrumb.component.html b/src/app/components/shared/breadcrumb/breadcrumb.component.html
new file mode 100644
index 0000000..e6cdba5
--- /dev/null
+++ b/src/app/components/shared/breadcrumb/breadcrumb.component.html
@@ -0,0 +1,26 @@
+<!--
+ ~ 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 [attr.aria-label]="'layout.main.breadcrumb' | translate">
+ <ol class="breadcrumb">
+ <li *ngFor="let item of items; index as i" class="breadcrumb-item">
+ <ng-container *ngTemplateOutlet="item.template" accessKey='3'></ng-container>
+ </li>
+ </ol>
+</nav>
diff --git a/src/app/components/shared/breadcrumb/breadcrumb.component.ts b/src/app/components/shared/breadcrumb/breadcrumb.component.ts
new file mode 100644
index 0000000..864a9ff
--- /dev/null
+++ b/src/app/components/shared/breadcrumb/breadcrumb.component.ts
@@ -0,0 +1,30 @@
+/*
+ * 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, ContentChildren, QueryList } from '@angular/core';
+import { BreadcrumbItemComponent } from '../breadcrumb-item/breadcrumb-item.component';
+
+@Component({
+ selector: 'app-breadcrumb',
+ templateUrl: './breadcrumb.component.html',
+})
+export class BreadcrumbComponent {
+ @ContentChildren(BreadcrumbItemComponent)
+ readonly items!: QueryList<BreadcrumbItemComponent>;
+}
diff --git a/src/app/components/shared/confirmation-modal/confirmation-modal.component.html b/src/app/components/shared/confirmation-modal/confirmation-modal.component.html
new file mode 100644
index 0000000..4f26c5d
--- /dev/null
+++ b/src/app/components/shared/confirmation-modal/confirmation-modal.component.html
@@ -0,0 +1,35 @@
+<!--
+ ~ 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
+ -->
+
+
+<div class="modal-header qa_modal_header">
+ <h4 class="modal-title qa_modal_title" id="modal-title">
+ <strong>{{ title }}</strong>
+ </h4>
+</div>
+<div class="modal-body qa_modal_body">
+ <p>
+ {{ text }}
+ </p>
+</div>
+<div *ngIf='showOkBtn || showCancelBtn' class="modal-footer qa_modal_footer">
+ <button *ngIf='showCancelBtn' type="button" class="btn btn-default qa_cancel_button" (click)="activeModal.close(false)">
+ {{ cancelText }}
+ </button>
+ <button *ngIf='showOkBtn' type="button" class="btn btn-danger qa_apply_button" (click)="activeModal.close(true)">{{ okText }}</button>
+</div>
diff --git a/src/app/components/shared/confirmation-modal/confirmation-modal.component.spec.ts b/src/app/components/shared/confirmation-modal/confirmation-modal.component.spec.ts
new file mode 100644
index 0000000..b7b5110
--- /dev/null
+++ b/src/app/components/shared/confirmation-modal/confirmation-modal.component.spec.ts
@@ -0,0 +1,19 @@
+/*
+ * 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
+ */
+
+
diff --git a/src/app/components/shared/confirmation-modal/confirmation-modal.component.ts b/src/app/components/shared/confirmation-modal/confirmation-modal.component.ts
new file mode 100644
index 0000000..023ba5e
--- /dev/null
+++ b/src/app/components/shared/confirmation-modal/confirmation-modal.component.ts
@@ -0,0 +1,39 @@
+/*
+ * 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, Input } from '@angular/core';
+import { TranslateService } from '@ngx-translate/core';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+
+@Component({
+ selector: 'app-confirmation-modal',
+ templateUrl: './confirmation-modal.component.html'
+})
+export class ConfirmationModalComponent {
+ constructor(public activeModal: NgbActiveModal, private readonly translateService: TranslateService) {}
+
+ @Input() showOkBtn = true;
+ @Input() showCancelBtn = true;
+
+ @Input()
+ okText = this.translateService.instant('common.buttons.save');
+ cancelText = this.translateService.instant('common.buttons.cancel');
+ title = '';
+ text = '';
+}
diff --git a/src/app/components/shared/loading-spinner/loading-spinner.component.html b/src/app/components/shared/loading-spinner/loading-spinner.component.html
new file mode 100644
index 0000000..f9dd6ab
--- /dev/null
+++ b/src/app/components/shared/loading-spinner/loading-spinner.component.html
@@ -0,0 +1,21 @@
+<!--
+ ~ 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
+ -->
+
+<div class="spinner-border spinner-border-sm text-light qa_alarm_spinner" role="status">
+ <span class="sr-only">{{'common.loading' | translate}}</span>
+</div>
diff --git a/src/app/components/shared/loading-spinner/loading-spinner.component.ts b/src/app/components/shared/loading-spinner/loading-spinner.component.ts
new file mode 100644
index 0000000..c99a085
--- /dev/null
+++ b/src/app/components/shared/loading-spinner/loading-spinner.component.ts
@@ -0,0 +1,26 @@
+/*
+ * 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 } from '@angular/core';
+
+@Component({
+ selector: 'app-loading-spinner',
+ templateUrl: './loading-spinner.component.html',
+})
+export class LoadingSpinnerComponent {
+}
diff --git a/src/app/components/shared/pagination/pagination.component.css b/src/app/components/shared/pagination/pagination.component.css
new file mode 100644
index 0000000..b864207
--- /dev/null
+++ b/src/app/components/shared/pagination/pagination.component.css
@@ -0,0 +1,23 @@
+/*
+ * 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
+ */
+
+
+ngb-pagination::ng-deep li .page-link:focus {
+ box-shadow: 0 0 0 0.2rem rgb(0 123 255 / 25%);
+ border-color: #00a0de;
+}
diff --git a/src/app/components/shared/pagination/pagination.component.html b/src/app/components/shared/pagination/pagination.component.html
new file mode 100644
index 0000000..ad198fc
--- /dev/null
+++ b/src/app/components/shared/pagination/pagination.component.html
@@ -0,0 +1,48 @@
+<!--
+ ~ 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
+ -->
+
+
+<div class="d-flex flex-wrap justify-content-between mt-3">
+ <div>
+ <ngb-pagination
+ [collectionSize]="collectionSize"
+ [pageSize]="pageSize"
+ [page]="page"
+ (pageChange)="emitPageChange($event)"
+ ></ngb-pagination>
+ <span class="ml-2 small">
+ {{ 'common.pagination.totalCount' | translate: { value: collectionSize } }}
+ </span>
+ </div>
+ <div>
+ <label for="item-select" class="sr-only">
+ {{ 'common.select.description' | translate }}
+ </label>
+ <select
+ id="item-select"
+ class="custom-select"
+ style="width: auto"
+ [ngModel]="pageSize"
+ (ngModelChange)="emitModelChange($event)"
+ >
+ <option *ngFor="let n of itemsPerPage" [ngValue]="n">
+ {{ 'common.select.itemsPerPage' | translate: { value: n } }}
+ </option>
+ </select>
+ </div>
+</div>
diff --git a/src/app/components/shared/pagination/pagination.component.spec.ts b/src/app/components/shared/pagination/pagination.component.spec.ts
new file mode 100644
index 0000000..7ffe9fc
--- /dev/null
+++ b/src/app/components/shared/pagination/pagination.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 { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { PaginationComponent } from './pagination.component';
+
+describe('PaginationComponent', () => {
+ let component: PaginationComponent;
+ let fixture: ComponentFixture<PaginationComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [PaginationComponent],
+ }).compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(PaginationComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/shared/pagination/pagination.component.ts b/src/app/components/shared/pagination/pagination.component.ts
new file mode 100644
index 0000000..fee827d
--- /dev/null
+++ b/src/app/components/shared/pagination/pagination.component.ts
@@ -0,0 +1,88 @@
+/*
+ * 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, EventEmitter, Input, Output } from '@angular/core';
+import { NgbPaginationConfig } from '@ng-bootstrap/ng-bootstrap';
+
+/**
+ * This is a wrapper component for the `ngbPagination` component of ngBootstrap ([official wiki page](https://ng-bootstrap.github.io/#/components/pagination/overview)).
+ * This contains the pagination element, as well as the selection element for the page size.
+ *
+ *
+ * Deal with both using the `pageChange` and `pageSizeChange` events, i.e in your template:
+ * ``` html
+ * <app-pagination
+ * [collectionSize]="..."
+ [pageSize]="..."
+ [page]="..."
+ * (pageChange)="changePage($event)"
+ * (pageSizeChange)="changePageSize($event)"
+ * >
+ * </app-pagination>
+ * ```
+ */
+@Component({
+ selector: 'app-pagination',
+ templateUrl: './pagination.component.html',
+ styleUrls: ['./pagination.component.css'],
+ providers: [NgbPaginationConfig],
+})
+export class PaginationComponent {
+ /**
+ * This event is fired when an item in the `select`-element is changed
+ */
+ @Output() pageSizeChange: EventEmitter<number> = new EventEmitter<number>();
+
+ /**
+ * Specify what page sizes should be selectable by the user.
+ */
+ @Input() itemsPerPage = [10, 20, 50];
+
+ @Output() pageChange: EventEmitter<number> = new EventEmitter<number>();
+ @Input() collectionSize = 10;
+ @Input() pageSize = 10;
+ @Input() page = 1;
+
+ constructor(config: NgbPaginationConfig) {
+ config.boundaryLinks = true;
+ config.directionLinks = true;
+ config.disabled = false;
+ config.ellipses = false;
+ config.maxSize = 3;
+ config.pageSize = 10;
+ config.rotate = true;
+ config.size = 'sm';
+ }
+
+ /**
+ * Emit the currently selected page from the `ngb-Pagination`
+ * @param page the page that is selected
+ */
+ emitPageChange(page: number) {
+ this.pageChange.emit(page);
+ }
+
+ /**
+ * Emit the currently selected page size from the `select`
+ * @param size the number of items per page that is selected
+ */
+ emitModelChange(size: number) {
+ this.pageSizeChange.emit(size);
+ }
+}
diff --git a/src/app/components/shared/status-page/status-page.component.css b/src/app/components/shared/status-page/status-page.component.css
new file mode 100644
index 0000000..b7b5110
--- /dev/null
+++ b/src/app/components/shared/status-page/status-page.component.css
@@ -0,0 +1,19 @@
+/*
+ * 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
+ */
+
+
diff --git a/src/app/components/shared/status-page/status-page.component.html b/src/app/components/shared/status-page/status-page.component.html
new file mode 100644
index 0000000..28e65c6
--- /dev/null
+++ b/src/app/components/shared/status-page/status-page.component.html
@@ -0,0 +1,23 @@
+<!--
+ ~ 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
+ -->
+
+
+<div class="d-flex justify-content-center align-items-center flex-column h-100">
+ <h2 class="text-center">{{header}}</h2>
+ <h3>{{message}}</h3>
+</div>
diff --git a/src/app/components/shared/status-page/status-page.component.spec.ts b/src/app/components/shared/status-page/status-page.component.spec.ts
new file mode 100644
index 0000000..f8c547e
--- /dev/null
+++ b/src/app/components/shared/status-page/status-page.component.spec.ts
@@ -0,0 +1,44 @@
+/*
+ * 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 { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { StatusPageComponent } from './status-page.component';
+
+describe('StatusPageComponent', () => {
+ let component: StatusPageComponent;
+ let fixture: ComponentFixture<StatusPageComponent>;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ StatusPageComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(StatusPageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/components/shared/status-page/status-page.component.ts b/src/app/components/shared/status-page/status-page.component.ts
new file mode 100644
index 0000000..3cbbf46
--- /dev/null
+++ b/src/app/components/shared/status-page/status-page.component.ts
@@ -0,0 +1,37 @@
+/*
+ * 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 } from '@angular/core';
+import { Router } from '@angular/router';
+
+@Component({
+ selector: 'app-status-page',
+ templateUrl: './status-page.component.html',
+ styleUrls: ['./status-page.component.css'],
+})
+export class StatusPageComponent {
+ header: string;
+ message: string;
+
+ constructor(private router: Router) {
+ const data = this.router.getCurrentNavigation();
+ this.header = data?.extras?.state?.header;
+ this.message = data?.extras?.state?.message;
+ }
+}
diff --git a/src/app/components/shared/table-skeleton/table-skeleton.component.css b/src/app/components/shared/table-skeleton/table-skeleton.component.css
new file mode 100644
index 0000000..0870694
--- /dev/null
+++ b/src/app/components/shared/table-skeleton/table-skeleton.component.css
@@ -0,0 +1,37 @@
+/*
+ * 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
+ */
+
+
+@keyframes ghost {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 100vw 0;
+ }
+}
+
+.line {
+ width: 100%;
+ height: 50px;
+ margin-top: 10px;
+ border-radius: 3px;
+ background: linear-gradient(90deg, #f0f0f0, #d8d6d6, #f0f0f0) 0 0/ 80vh 100% fixed;
+ background-color: var(--secondary);
+ animation: ghost 4000ms infinite linear;
+}
diff --git a/src/app/components/shared/table-skeleton/table-skeleton.component.html b/src/app/components/shared/table-skeleton/table-skeleton.component.html
new file mode 100644
index 0000000..717da1f
--- /dev/null
+++ b/src/app/components/shared/table-skeleton/table-skeleton.component.html
@@ -0,0 +1,31 @@
+<!--
+ ~ 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
+ -->
+
+
+<div id="table-skeleton">
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+ <div class="line"></div>
+</div>
diff --git a/src/app/components/shared/table-skeleton/table-skeleton.component.ts b/src/app/components/shared/table-skeleton/table-skeleton.component.ts
new file mode 100644
index 0000000..41638fe
--- /dev/null
+++ b/src/app/components/shared/table-skeleton/table-skeleton.component.ts
@@ -0,0 +1,29 @@
+/*
+ * 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 { ChangeDetectionStrategy, Component } from '@angular/core';
+
+@Component({
+ selector: 'app-table-skeleton',
+ templateUrl: './table-skeleton.component.html',
+ styleUrls: ['./table-skeleton.component.css'],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class TableSkeletonComponent {
+}