You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ri...@apache.org on 2022/07/07 20:53:14 UTC

[incubator-streampipes] branch dev updated (a1080a830 -> c2e00b82d)

This is an automated email from the ASF dual-hosted git repository.

riemer pushed a change to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git


    from a1080a830 [hotfix] Fix positioning bug for auto-generated pipelines
     new 3a2c2a681 [STREAMPIPES-537] Add reusable tab-based navbar component
     new c2e00b82d [STREAMPIPES-537] Use reusable tabs component in configuration view

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../basic-nav-tabs/basic-nav-tabs.component.html}  |  23 ++--
 .../basic-nav-tabs.component.scss}                 |  14 +--
 .../basic-nav-tabs.component.ts}                   |  20 ++--
 .../src/lib/models/sp-navigation.model.ts          |   8 +-
 .../shared-ui/src/lib/shared-ui.module.ts          |  17 ++-
 .../streampipes/shared-ui/src/public-api.ts        |   3 +
 .../configuration-tabs.ts}                         |  23 ++--
 ui/src/app/configuration/configuration.module.ts   |   2 +
 .../datalake-configuration.component.html          |   4 +-
 .../datalake-configuration.component.ts            |   3 +
 .../email-configuration.component.html             |   4 +-
 .../email-configuration.component.ts               |   3 +
 .../general-configuration.component.html           |   4 +-
 .../general-configuration.component.ts             |   3 +
 .../messaging-configuration.component.html         |   4 +-
 .../messaging-configuration.component.ts           |   3 +
 .../pipeline-element-configuration.component.html  |   4 +-
 .../pipeline-element-configuration.component.ts    | 133 +++++++++++----------
 .../security-configuration.component.html          |   4 +-
 .../security-configuration.component.ts            |   3 +
 20 files changed, 158 insertions(+), 124 deletions(-)
 copy ui/{src/app/app-asset-monitoring/components/view-asset/view-asset.component.html => projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html} (55%)
 copy ui/projects/streampipes/shared-ui/src/lib/components/{basic-view/basic-view.component.scss => basic-nav-tabs/basic-nav-tabs.component.scss} (86%)
 copy ui/projects/streampipes/shared-ui/src/lib/components/{basic-view/basic-view.component.ts => basic-nav-tabs/basic-nav-tabs.component.ts} (70%)
 copy streampipes-commons/src/main/java/org/apache/streampipes/commons/exceptions/NoValidSepTypeException.java => ui/projects/streampipes/shared-ui/src/lib/models/sp-navigation.model.ts (89%)
 copy ui/src/app/{data-explorer/components/widgets/table/model/table-widget.model.ts => configuration/configuration-tabs.ts} (53%)


[incubator-streampipes] 02/02: [STREAMPIPES-537] Use reusable tabs component in configuration view

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git

commit c2e00b82dc454b8457d7279c62786bc5bd1add38
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Thu Jul 7 22:53:06 2022 +0200

    [STREAMPIPES-537] Use reusable tabs component in configuration view
---
 ...guration.component.ts => configuration-tabs.ts} |  22 ++--
 ui/src/app/configuration/configuration.module.ts   |   2 +
 .../datalake-configuration.component.html          |   4 +-
 .../datalake-configuration.component.ts            |   3 +
 .../email-configuration.component.html             |   4 +-
 .../email-configuration.component.ts               |   3 +
 .../general-configuration.component.html           |   4 +-
 .../general-configuration.component.ts             |   3 +
 .../messaging-configuration.component.html         |   4 +-
 .../messaging-configuration.component.ts           |   3 +
 .../pipeline-element-configuration.component.html  |   4 +-
 .../pipeline-element-configuration.component.ts    | 133 +++++++++++----------
 .../security-configuration.component.html          |   4 +-
 .../security-configuration.component.ts            |   3 +
 14 files changed, 109 insertions(+), 87 deletions(-)

diff --git a/ui/src/app/configuration/security-configuration/security-configuration.component.ts b/ui/src/app/configuration/configuration-tabs.ts
similarity index 52%
copy from ui/src/app/configuration/security-configuration/security-configuration.component.ts
copy to ui/src/app/configuration/configuration-tabs.ts
index 427c982fb..dba3af875 100644
--- a/ui/src/app/configuration/security-configuration/security-configuration.component.ts
+++ b/ui/src/app/configuration/configuration-tabs.ts
@@ -16,18 +16,18 @@
  *
  */
 
-import { Component, OnInit } from '@angular/core';
+import { SpNavigationItem } from '@streampipes/shared-ui';
 
-@Component({
-  selector: 'sp-security-configuration',
-  templateUrl: './security-configuration.component.html',
-  styleUrls: ['./security-configuration.component.scss']
-})
-export class SecurityConfigurationComponent implements OnInit {
+export class SpConfigurationTabs {
 
-  constructor() {}
-
-  ngOnInit(): void {
+  public static getTabs(): SpNavigationItem[] {
+    return [
+      {itemId: 'general', itemTitle: 'General', itemLink: ['configuration', 'general']},
+      {itemId: 'datalake', itemTitle: 'Data Lake', itemLink: ['configuration', 'datalake']},
+      {itemId: 'email', itemTitle: 'Mail', itemLink: ['configuration', 'email']},
+      {itemId: 'messaging', itemTitle: 'Messaging', itemLink: ['configuration', 'messaging']},
+      {itemId: 'pipelineelement', itemTitle: 'Pipeline Element Configuration', itemLink: ['configuration', 'pipelineelement']},
+      {itemId: 'security', itemTitle: 'Security', itemLink: ['configuration', 'security']}
+    ];
   }
-
 }
diff --git a/ui/src/app/configuration/configuration.module.ts b/ui/src/app/configuration/configuration.module.ts
index 88e351b1f..4bb6be8ef 100644
--- a/ui/src/app/configuration/configuration.module.ts
+++ b/ui/src/app/configuration/configuration.module.ts
@@ -55,6 +55,7 @@ import { EmailConfigurationComponent } from "./email-configuration/email-configu
 import { GeneralConfigurationComponent } from "./general-configuration/general-configuration.component";
 import { SecurityAuthenticationConfigurationComponent } from "./security-configuration/authentication-configuration/authentication-configuration.component";
 import { RouterModule } from "@angular/router";
+import { SharedUiModule } from '../../../dist/streampipes/shared-ui';
 
 @NgModule({
   imports: [
@@ -110,6 +111,7 @@ import { RouterModule } from "@angular/router";
         ]
       }
     ]),
+    SharedUiModule,
   ],
   declarations: [
     ConfigurationComponent,
diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
index bc576c09b..07c6c0f3a 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
@@ -17,7 +17,7 @@
   -->
 
 
-<sp-configuration-component [activeLink]="'datalake'">
+<sp-basic-nav-tabs [spNavigationItems]="tabs" [activeLink]="'datalake'">
     <div fxLayout="row" class="page-container-padding">
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
             <sp-split-section title="Data Lake Settings" subtitle="Truncate and delete persisted data streams">
@@ -94,4 +94,4 @@
             </sp-split-section>
         </div>
     </div>
-</sp-configuration-component>
\ No newline at end of file
+</sp-basic-nav-tabs>
diff --git a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
index 7f6986d6a..de2f2cad2 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.ts
@@ -32,6 +32,7 @@ import { MatPaginator } from '@angular/material/paginator';
 import { MatSort } from '@angular/material/sort';
 import { DialogRef, DialogService, PanelType } from '@streampipes/shared-ui';
 import { DeleteDatalakeIndexComponent } from '../dialog/delete-datalake-index/delete-datalake-index-dialog.component';
+import { SpConfigurationTabs } from '../configuration-tabs';
 
 @Component({
   selector: 'sp-datalake-configuration',
@@ -40,6 +41,8 @@ import { DeleteDatalakeIndexComponent } from '../dialog/delete-datalake-index/de
 })
 export class DatalakeConfigurationComponent implements OnInit {
 
+  tabs = SpConfigurationTabs.getTabs();
+
   @ViewChild(MatPaginator) paginator: MatPaginator;
   pageSize = 1;
   @ViewChild(MatSort) sort: MatSort;
diff --git a/ui/src/app/configuration/email-configuration/email-configuration.component.html b/ui/src/app/configuration/email-configuration/email-configuration.component.html
index 3eff4b18f..b6994e3ed 100644
--- a/ui/src/app/configuration/email-configuration/email-configuration.component.html
+++ b/ui/src/app/configuration/email-configuration/email-configuration.component.html
@@ -16,7 +16,7 @@
   ~
   -->
 
-<sp-configuration-component [activeLink]="'email'">
+<sp-basic-nav-tabs [spNavigationItems]="tabs" [activeLink]="'email'">
     <div fxLayout="column" class="page-container-padding">
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" *ngIf="formReady">
             <sp-split-section title="Mail Settings" subtitle="Settings to connect to a mail server">
@@ -113,4 +113,4 @@
 
 
     </div>
-</sp-configuration-component>
\ No newline at end of file
+</sp-basic-nav-tabs>
diff --git a/ui/src/app/configuration/email-configuration/email-configuration.component.ts b/ui/src/app/configuration/email-configuration/email-configuration.component.ts
index 698780c2e..1ed2cbdca 100644
--- a/ui/src/app/configuration/email-configuration/email-configuration.component.ts
+++ b/ui/src/app/configuration/email-configuration/email-configuration.component.ts
@@ -19,6 +19,7 @@
 import { Component, OnInit } from '@angular/core';
 import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
 import { EmailConfig, MailConfigService } from '@streampipes/platform-services';
+import { SpConfigurationTabs } from '../configuration-tabs';
 
 @Component({
   selector: 'sp-email-configuration',
@@ -27,6 +28,8 @@ import { EmailConfig, MailConfigService } from '@streampipes/platform-services';
 })
 export class EmailConfigurationComponent implements OnInit {
 
+  tabs = SpConfigurationTabs.getTabs();
+
   parentForm: FormGroup;
 
   mailConfig: EmailConfig;
diff --git a/ui/src/app/configuration/general-configuration/general-configuration.component.html b/ui/src/app/configuration/general-configuration/general-configuration.component.html
index 3be142995..b6cfae4b5 100644
--- a/ui/src/app/configuration/general-configuration/general-configuration.component.html
+++ b/ui/src/app/configuration/general-configuration/general-configuration.component.html
@@ -15,7 +15,7 @@
   ~ limitations under the License.
   ~
   -->
-<sp-configuration-component [activeLink]="'general'">
+<sp-basic-nav-tabs [spNavigationItems]="tabs" [activeLink]="'general'">
     <div fxLayout="column" class="page-container-padding">
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" *ngIf="formReady">
             <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
@@ -89,4 +89,4 @@
         </div>
 
     </div>
-</sp-configuration-component>
+</sp-basic-nav-tabs>
diff --git a/ui/src/app/configuration/general-configuration/general-configuration.component.ts b/ui/src/app/configuration/general-configuration/general-configuration.component.ts
index 7c3a787e2..355922cda 100644
--- a/ui/src/app/configuration/general-configuration/general-configuration.component.ts
+++ b/ui/src/app/configuration/general-configuration/general-configuration.component.ts
@@ -24,6 +24,7 @@ import { AvailableRolesService } from '../../services/available-roles.service';
 import { RoleDescription } from '../../_models/auth.model';
 import { UserRole } from '../../_enums/user-role.enum';
 import { AppConstants } from '../../services/app.constants';
+import { SpConfigurationTabs } from '../configuration-tabs';
 
 @Component({
   selector: 'sp-general-configuration',
@@ -32,6 +33,8 @@ import { AppConstants } from '../../services/app.constants';
 })
 export class GeneralConfigurationComponent implements OnInit {
 
+  tabs = SpConfigurationTabs.getTabs();
+
   parentForm: FormGroup;
   formReady = false;
 
diff --git a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
index 57f31bd8d..ed44cf600 100644
--- a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
+++ b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
@@ -16,7 +16,7 @@
   ~
   -->
 
-<sp-configuration-component [activeLink]="'messaging'">
+<sp-basic-nav-tabs [spNavigationItems]="tabs" [activeLink]="'messaging'">
     <div fxLayout="column" class="page-container-padding">
         <sp-split-section title="Kafka Settings" subtitle="Manage Kafka settings for pipeline communication">
             <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="page-container-padding-inner">
@@ -83,4 +83,4 @@
             </div>
         </sp-split-section>
     </div>
-</sp-configuration-component>
+</sp-basic-nav-tabs>
diff --git a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts
index 51a79ed44..04e6687fe 100644
--- a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts
+++ b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.ts
@@ -20,6 +20,7 @@ import { Component, OnInit } from '@angular/core';
 import { ConfigurationService } from '../shared/configuration.service';
 import { MessagingSettings } from '../shared/messaging-settings.model';
 import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
+import { SpConfigurationTabs } from '../configuration-tabs';
 
 @Component({
     selector: 'messaging-configuration',
@@ -28,6 +29,8 @@ import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
 })
 export class MessagingConfigurationComponent implements OnInit {
 
+    tabs = SpConfigurationTabs.getTabs();
+
     messagingSettings: MessagingSettings;
     loadingCompleted = false;
 
diff --git a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html
index 31c942a73..e7caaa035 100644
--- a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html
+++ b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html
@@ -16,7 +16,7 @@
   ~
   -->
 
-<sp-configuration-component [activeLink]="'pipelineelement'">
+<sp-basic-nav-tabs [spNavigationItems]="tabs" [activeLink]="'pipelineelement'">
     <div fxLayout="row" class="page-container-padding">
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
             <sp-split-section title="Pipeline Element Configuration"
@@ -75,4 +75,4 @@
             </sp-split-section>
         </div>
     </div>
-</sp-configuration-component>
+</sp-basic-nav-tabs>
diff --git a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts
index 56e2ff398..b94253733 100644
--- a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts
+++ b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.ts
@@ -23,85 +23,90 @@ import { StreampipesPeContainer } from '../shared/streampipes-pe-container.model
 import { StreampipesPeContainerConifgs } from '../shared/streampipes-pe-container-configs';
 import { MatPaginator } from '@angular/material/paginator';
 import { MatTableDataSource } from '@angular/material/table';
+import { SpConfigurationTabs } from '../configuration-tabs';
 
 @Component({
-    selector: 'pipeline-element-configuration',
-    templateUrl: './pipeline-element-configuration.component.html',
-    styleUrls: ['./pipeline-element-configuration.component.css'],
-    animations: [
-        trigger('detailExpand', [
-            state('collapsed', style({height: '0px', minHeight: '0', display: 'none'})),
-            state('expanded', style({height: '*'})),
-            transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
-        ]),
-    ]
+  selector: 'pipeline-element-configuration',
+  templateUrl: './pipeline-element-configuration.component.html',
+  styleUrls: ['./pipeline-element-configuration.component.css'],
+  animations: [
+    trigger('detailExpand', [
+      state('collapsed', style({height: '0px', minHeight: '0', display: 'none'})),
+      state('expanded', style({height: '*'})),
+      transition('expanded <=> collapsed', animate('225ms cubic-bezier(0.4, 0.0, 0.2, 1)')),
+    ]),
+  ]
 })
 export class PipelineElementConfigurationComponent {
 
-    consulServices: StreampipesPeContainer[];
+  tabs = SpConfigurationTabs.getTabs();
 
-    displayedColumns: string[] = ['status', 'name', 'action'];
-    @ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
-    dataSource = new MatTableDataSource<StreampipesPeContainer>();
+  consulServices: StreampipesPeContainer[];
 
-    expandedElement: any;
+  displayedColumns: string[] = ['status', 'name', 'action'];
+  @ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
+  dataSource = new MatTableDataSource<StreampipesPeContainer>();
 
-    selectedConsulService: StreampipesPeContainer;
-    consulServiceSelected = false;
+  expandedElement: any;
 
-    constructor(private configurationService: ConfigurationService) {
-        this.getConsulServices();
-    }
+  selectedConsulService: StreampipesPeContainer;
+  consulServiceSelected = false;
 
-    getConsulServices(): void {
-        this.configurationService.getConsulServices()
-            .subscribe( response => {
-                const sortedServices = this.sort(response);
-                this.consulServices = sortedServices;
-                this.dataSource.data = sortedServices;
-            }, error => {
-                console.error(error);
-            });
-    }
+  constructor(private configurationService: ConfigurationService) {
+    this.getConsulServices();
+  }
 
-    sort(consulServices: StreampipesPeContainer[]): StreampipesPeContainer[] {
-        if (!consulServices || consulServices.length === 0) { return null; }
+  getConsulServices(): void {
+    this.configurationService.getConsulServices()
+      .subscribe(response => {
+        const sortedServices = this.sort(response);
+        this.consulServices = sortedServices;
+        this.dataSource.data = sortedServices;
+      }, error => {
+        console.error(error);
+      });
+  }
 
-        consulServices.sort((a: StreampipesPeContainer, b: StreampipesPeContainer) => {
-            if (a.name < b.name) {
-                return -1;
-            } else if (a.name > b.name) {
-                return 1;
-            } else {
-                return 0;
-            }
-        });
-        consulServices.forEach(cs => cs.configs.sort((a: StreampipesPeContainerConifgs, b: StreampipesPeContainerConifgs) => {
-            if (a.key < b.key) {
-                return -1;
-            } else if (a.key > b.key) {
-                return 1;
-            } else {
-                return 0;
-            }
-        }));
-        return consulServices;
+  sort(consulServices: StreampipesPeContainer[]): StreampipesPeContainer[] {
+    if (!consulServices || consulServices.length === 0) {
+      return null;
     }
 
-    updateConsulService(consulService: StreampipesPeContainer): void {
-        this.configurationService.updateConsulService(consulService)
-            .subscribe(response => {
+    consulServices.sort((a: StreampipesPeContainer, b: StreampipesPeContainer) => {
+      if (a.name < b.name) {
+        return -1;
+      } else if (a.name > b.name) {
+        return 1;
+      } else {
+        return 0;
+      }
+    });
+    consulServices.forEach(cs => cs.configs.sort((a: StreampipesPeContainerConifgs, b: StreampipesPeContainerConifgs) => {
+      if (a.key < b.key) {
+        return -1;
+      } else if (a.key > b.key) {
+        return 1;
+      } else {
+        return 0;
+      }
+    }));
+    return consulServices;
+  }
 
-            }, error => {
-                console.error(error);
-            });
-    }
+  updateConsulService(consulService: StreampipesPeContainer): void {
+    this.configurationService.updateConsulService(consulService)
+      .subscribe(response => {
+
+      }, error => {
+        console.error(error);
+      });
+  }
 
-    expand(element: StreampipesPeContainer) {
-        if (this.expandedElement === element) {
-            this.expandedElement = undefined;
-        } else {
-            this.expandedElement = element;
-        }
+  expand(element: StreampipesPeContainer) {
+    if (this.expandedElement === element) {
+      this.expandedElement = undefined;
+    } else {
+      this.expandedElement = element;
     }
+  }
 }
diff --git a/ui/src/app/configuration/security-configuration/security-configuration.component.html b/ui/src/app/configuration/security-configuration/security-configuration.component.html
index f5a8acb83..837e84154 100644
--- a/ui/src/app/configuration/security-configuration/security-configuration.component.html
+++ b/ui/src/app/configuration/security-configuration/security-configuration.component.html
@@ -16,7 +16,7 @@
   ~
   -->
 
-<sp-configuration-component [activeLink]="'security'">
+<sp-basic-nav-tabs [spNavigationItems]="tabs" [activeLink]="'security'">
     <div fxLayout="column" class="page-container-padding">
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
             <sp-split-section title="User Accounts" subtitle="Add and edit user accounts">
@@ -46,4 +46,4 @@
             </sp-split-section>
         </div>
     </div>
-</sp-configuration-component>
+</sp-basic-nav-tabs>
diff --git a/ui/src/app/configuration/security-configuration/security-configuration.component.ts b/ui/src/app/configuration/security-configuration/security-configuration.component.ts
index 427c982fb..7c33b307b 100644
--- a/ui/src/app/configuration/security-configuration/security-configuration.component.ts
+++ b/ui/src/app/configuration/security-configuration/security-configuration.component.ts
@@ -17,6 +17,7 @@
  */
 
 import { Component, OnInit } from '@angular/core';
+import { SpConfigurationTabs } from '../configuration-tabs';
 
 @Component({
   selector: 'sp-security-configuration',
@@ -25,6 +26,8 @@ import { Component, OnInit } from '@angular/core';
 })
 export class SecurityConfigurationComponent implements OnInit {
 
+  tabs = SpConfigurationTabs.getTabs();
+
   constructor() {}
 
   ngOnInit(): void {


[incubator-streampipes] 01/02: [STREAMPIPES-537] Add reusable tab-based navbar component

Posted by ri...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

riemer pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git

commit 3a2c2a6812923e363a9a9d47d6843382e670acf7
Author: Dominik Riemer <do...@gmail.com>
AuthorDate: Thu Jul 7 22:52:41 2022 +0200

    [STREAMPIPES-537] Add reusable tab-based navbar component
---
 .../basic-nav-tabs/basic-nav-tabs.component.html   | 37 ++++++++++++++++++++++
 .../basic-nav-tabs/basic-nav-tabs.component.scss}  | 28 +++++++++++-----
 .../basic-nav-tabs/basic-nav-tabs.component.ts}    | 28 +++++++++++-----
 .../models/sp-navigation.model.ts}                 | 18 +++--------
 .../shared-ui/src/lib/shared-ui.module.ts          | 17 +++++++---
 .../streampipes/shared-ui/src/public-api.ts        |  3 ++
 6 files changed, 98 insertions(+), 33 deletions(-)

diff --git a/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html
new file mode 100644
index 000000000..25f3eadd1
--- /dev/null
+++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.html
@@ -0,0 +1,37 @@
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You 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.
+  ~
+  -->
+
+<div fxLayout="column" class="page-container">
+    <div fxLayout="row" class="p-0 sp-bg-lightgray page-container-nav">
+        <div fxLayout="fill">
+            <div fxFlex="100" class="page-container-nav">
+                <nav mat-tab-nav-bar color="accent">
+                    <a mat-tab-link *ngFor="let item of spNavigationItems"
+                       (click)="navigateTo(item)"
+                       [active]="activeLink === item.itemId">
+                        <span class="upper-case">{{item.itemTitle}}</span>
+                    </a>
+                </nav>
+            </div>
+        </div>
+    </div>
+
+    <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100">
+        <ng-content fxFlex="100"></ng-content>
+    </div>
+</div>
diff --git a/ui/projects/streampipes/shared-ui/src/public-api.ts b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.scss
similarity index 62%
copy from ui/projects/streampipes/shared-ui/src/public-api.ts
copy to ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.scss
index cd25a6bd7..ce626dc9d 100644
--- a/ui/projects/streampipes/shared-ui/src/public-api.ts
+++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.scss
@@ -16,16 +16,28 @@
  *
  */
 
-export * from './lib/shared-ui.module';
+.page-container-padding-inner {
+  padding: 10px;
+}
 
-export * from './lib/dialog/base-dialog/base-dialog.model';
-export * from './lib/dialog/base-dialog/base-dialog.service';
-export * from './lib/dialog/base-dialog/dialog-ref';
+.sp-bg-lightgray {
+  background-color: var(--color-bg-1);
+}
 
-export * from './lib/dialog/confirm-dialog/confirm-dialog.component';
-export * from './lib/dialog/panel-dialog/panel-dialog.component';
-export * from './lib/dialog/standard-dialog/standard-dialog.component';
+.sp-tab-bg {
+  background-color: var(--color-bg-1);
+}
 
-export * from './lib/components/basic-view/basic-view.component';
+.page-container {
+  margin: 10px;
+  border: 1px solid var(--color-bg-3);
+  min-height: calc(100% - 20px);
+}
 
+.page-container-padding-inner {
+  margin: 10px;
+}
 
+.upper-case {
+  text-transform: uppercase;
+}
diff --git a/ui/projects/streampipes/shared-ui/src/public-api.ts b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.ts
similarity index 57%
copy from ui/projects/streampipes/shared-ui/src/public-api.ts
copy to ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.ts
index cd25a6bd7..bdace86dd 100644
--- a/ui/projects/streampipes/shared-ui/src/public-api.ts
+++ b/ui/projects/streampipes/shared-ui/src/lib/components/basic-nav-tabs/basic-nav-tabs.component.ts
@@ -16,16 +16,28 @@
  *
  */
 
-export * from './lib/shared-ui.module';
+import { Component, Input } from '@angular/core';
+import { Router } from '@angular/router';
+import { SpNavigationItem } from '../../models/sp-navigation.model';
 
-export * from './lib/dialog/base-dialog/base-dialog.model';
-export * from './lib/dialog/base-dialog/base-dialog.service';
-export * from './lib/dialog/base-dialog/dialog-ref';
+@Component({
+  selector: 'sp-basic-nav-tabs',
+  templateUrl: './basic-nav-tabs.component.html',
+  styleUrls: ['./basic-nav-tabs.component.scss']
+})
+export class SpBasicNavTabsComponent {
 
-export * from './lib/dialog/confirm-dialog/confirm-dialog.component';
-export * from './lib/dialog/panel-dialog/panel-dialog.component';
-export * from './lib/dialog/standard-dialog/standard-dialog.component';
+  @Input()
+  spNavigationItems: SpNavigationItem[];
 
-export * from './lib/components/basic-view/basic-view.component';
+  @Input()
+  activeLink: string;
 
+  constructor(private router: Router) {
 
+  }
+
+  navigateTo(spNavigationItem: SpNavigationItem) {
+    this.router.navigate(spNavigationItem.itemLink);
+  }
+}
diff --git a/ui/projects/streampipes/shared-ui/src/public-api.ts b/ui/projects/streampipes/shared-ui/src/lib/models/sp-navigation.model.ts
similarity index 61%
copy from ui/projects/streampipes/shared-ui/src/public-api.ts
copy to ui/projects/streampipes/shared-ui/src/lib/models/sp-navigation.model.ts
index cd25a6bd7..d9d9938ec 100644
--- a/ui/projects/streampipes/shared-ui/src/public-api.ts
+++ b/ui/projects/streampipes/shared-ui/src/lib/models/sp-navigation.model.ts
@@ -16,16 +16,8 @@
  *
  */
 
-export * from './lib/shared-ui.module';
-
-export * from './lib/dialog/base-dialog/base-dialog.model';
-export * from './lib/dialog/base-dialog/base-dialog.service';
-export * from './lib/dialog/base-dialog/dialog-ref';
-
-export * from './lib/dialog/confirm-dialog/confirm-dialog.component';
-export * from './lib/dialog/panel-dialog/panel-dialog.component';
-export * from './lib/dialog/standard-dialog/standard-dialog.component';
-
-export * from './lib/components/basic-view/basic-view.component';
-
-
+export interface SpNavigationItem {
+  itemId: string;
+  itemTitle: string;
+  itemLink: string[];
+}
diff --git a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
index 7d26b8e54..1758565cf 100644
--- a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
+++ b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
@@ -28,25 +28,34 @@ import { SpBasicViewComponent } from './components/basic-view/basic-view.compone
 import { FlexLayoutModule } from '@angular/flex-layout';
 import { MatIconModule } from '@angular/material/icon';
 import { MatTooltipModule } from '@angular/material/tooltip';
+import { SpBasicNavTabsComponent } from './components/basic-nav-tabs/basic-nav-tabs.component';
+import { MatTabsModule } from '@angular/material/tabs';
 
 @NgModule({
   declarations: [
     ConfirmDialogComponent,
     PanelDialogComponent,
     StandardDialogComponent,
-    SpBasicViewComponent
+    SpBasicViewComponent,
+    SpBasicNavTabsComponent
   ],
   imports: [
     CommonModule,
     FlexLayoutModule,
     MatButtonModule,
     MatIconModule,
+    MatTabsModule,
     MatTooltipModule,
     PortalModule,
-    OverlayModule
+    OverlayModule,
   ],
   exports: [
-    ConfirmDialogComponent, PanelDialogComponent, StandardDialogComponent, SpBasicViewComponent
+    ConfirmDialogComponent,
+    PanelDialogComponent,
+    StandardDialogComponent,
+    SpBasicViewComponent,
+    SpBasicNavTabsComponent,
   ]
 })
-export class SharedUiModule { }
+export class SharedUiModule {
+}
diff --git a/ui/projects/streampipes/shared-ui/src/public-api.ts b/ui/projects/streampipes/shared-ui/src/public-api.ts
index cd25a6bd7..007b7cd99 100644
--- a/ui/projects/streampipes/shared-ui/src/public-api.ts
+++ b/ui/projects/streampipes/shared-ui/src/public-api.ts
@@ -28,4 +28,7 @@ export * from './lib/dialog/standard-dialog/standard-dialog.component';
 
 export * from './lib/components/basic-view/basic-view.component';
 
+export * from './lib/components/basic-nav-tabs/basic-nav-tabs.component';
+export * from './lib/models/sp-navigation.model';
+