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

riemer pushed a commit to branch 3114-improve-pipeline-details-view
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to 
refs/heads/3114-improve-pipeline-details-view by this push:
     new 5ae411cbbb feat(#3114): Improve pipeline details view
5ae411cbbb is described below

commit 5ae411cbbb04ad63601e271bf57c92839b71a22a
Author: Dominik Riemer <[email protected]>
AuthorDate: Thu Aug 8 17:46:33 2024 +0200

    feat(#3114): Improve pipeline details view
---
 .../pipeline-assembly.component.scss               |   8 +-
 .../pipeline-element-icon-stand-row.component.html |   1 -
 ...peline-element-statistics-badge.component.html} |  27 +---
 ...peline-element-statistics-badge.component.scss} |  20 ++-
 ...pipeline-element-statistics-badge.component.ts} |  15 +-
 .../pipeline-element-statistics.component.html}    |  33 ++--
 .../pipeline-element-statistics.component.scss}    |  24 ++-
 .../pipeline-element-statistics.component.ts}      |  42 +++---
 .../pipeline-element.component.html                |   2 +-
 .../pipeline-element/pipeline-element.component.ts |   5 -
 .../components/pipeline/pipeline.component.html    |   7 +-
 .../components/pipeline/pipeline.component.ts      |  81 ++++------
 ui/src/app/editor/editor.module.ts                 |   4 +
 ui/src/app/editor/model/editor.model.ts            |   1 -
 .../app/editor/services/jsplumb-config.service.ts  |   4 -
 .../editor/services/jsplumb-endpoint.service.ts    |  26 ++--
 ui/src/app/editor/services/jsplumb.service.ts      |  13 +-
 .../services/pipeline-positioning.service.ts       |  14 +-
 .../actions/pipeline-actions.component.html        |  89 -----------
 .../monitoring/pipeline-monitoring.component.html  | 113 --------------
 .../monitoring/pipeline-monitoring.component.ts    | 154 -------------------
 .../pipeline-element-statistics.component.html     |  73 ---------
 .../pipeline-element-statistics.component.ts       | 144 ------------------
 .../pipeline-details-overview.component.html       |  65 --------
 .../pipeline-details-overview.component.ts         |  74 ---------
 .../actions/pipeline-actions.component.html        |  83 +++++++++++
 .../actions/pipeline-actions.component.ts          |  20 +--
 ...pipeline-details-expansion-panel.component.html |  56 +++++++
 ...ipeline-details-expansion-panel.component.scss} |  18 ++-
 .../pipeline-details-expansion-panel.component.ts} |  47 +++---
 .../elements/pipeline-elements-row.component.html  |  33 ++--
 .../elements/pipeline-elements-row.component.ts    |  27 +---
 .../pipeline-element-details-row.component.html}   |  24 ++-
 .../pipeline-element-details-row.component.scss    |   0
 .../pipeline-element-details-row.component.ts      |  52 +++++++
 .../status/pipeline-status.component.html          |  52 +++++++
 .../status/pipeline-status.component.scss}         |   7 +-
 .../status/pipeline-status.component.ts            |   3 +-
 .../pipeline-details-toolbar.component.html}       |  35 +++--
 .../pipeline-details-toolbar.component.ts}         |  19 ++-
 .../pipeline-logs/pipeline-logs.component.html     |  85 -----------
 .../pipeline-logs/pipeline-logs.component.scss     |  17 ---
 .../pipeline-logs/pipeline-logs.component.ts       |  96 ------------
 .../preview/pipeline-preview.component.html        |  25 ++--
 .../preview/pipeline-preview.component.ts          |  26 ++--
 .../components/sp-pipeline-details.directive.ts    |  76 ----------
 .../status/pipeline-status.component.html          |  66 --------
 .../pipeline-logs-dialog.component.html            |  48 ++++++
 .../pipeline-logs-dialog.component.scss}           |   0
 .../pipeline-logs-dialog.component.ts}             |  41 ++---
 .../app/pipeline-details/pipeline-details-tabs.ts  |  41 -----
 .../pipeline-details.component.html                |  55 +++++++
 ...ponent.scss => pipeline-details.component.scss} |  14 +-
 .../pipeline-details/pipeline-details.component.ts | 166 +++++++++++++++++++++
 .../pipeline-details/pipeline-details.module.ts    |  38 ++---
 ui/src/app/pipelines/pipelines.module.ts           |  13 +-
 ui/src/scss/sp/main.scss                           |   4 +-
 57 files changed, 844 insertions(+), 1482 deletions(-)

diff --git 
a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
 
b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
index df77313f0e..7d714593ef 100644
--- 
a/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
+++ 
b/ui/src/app/editor/components/pipeline-assembly/pipeline-assembly.component.scss
@@ -32,12 +32,8 @@
 }
 
 .outerAssembly {
-    //position: relative;
-    left: 0px;
-    top: 0px;
-    //overflow: visible;
-    //box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, 
.14), 0 2px 1px -1px rgba(0, 0, 0, .12);
-    //padding: 5px;
+    left: 0;
+    top: 0;
     display: flex;
     flex: 1 1 0;
     overflow: hidden;
diff --git 
a/ui/src/app/editor/components/pipeline-element-icon-stand-row/pipeline-element-icon-stand-row.component.html
 
b/ui/src/app/editor/components/pipeline-element-icon-stand-row/pipeline-element-icon-stand-row.component.html
index 8aeaa0c53d..85f43b9f27 100644
--- 
a/ui/src/app/editor/components/pipeline-element-icon-stand-row/pipeline-element-icon-stand-row.component.html
+++ 
b/ui/src/app/editor/components/pipeline-element-icon-stand-row/pipeline-element-icon-stand-row.component.html
@@ -39,7 +39,6 @@
                     [iconStandSize]="true"
                     [attr.data-cy]="'sp-pipeline-element-' + cypressName"
                     [pipelineElement]="element"
-                    [preview]="false"
                 ></sp-pipeline-element>
             </span>
         </div>
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.html
 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.html
similarity index 58%
rename from 
ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.html
rename to 
ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.html
index da3da6a3d9..aabb1197dc 100644
--- 
a/ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.html
+++ 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.html
@@ -16,28 +16,7 @@
   ~
   -->
 
-<div
-    fxFlex="100"
-    fxLayoutAlign="center center"
-    fxLayout="column"
-    [ngStyle]="{
-        'background-color': backgroundColor,
-        'width': '265px',
-        'max-width': '265px',
-        'margin-left': '8px'
-    }"
->
-    <ngx-charts-bar-vertical
-        [view]="[265, 150]"
-        [results]="data"
-        [scheme]="colorScheme"
-        [gradient]="false"
-        [xAxis]="false"
-        [yAxis]="true"
-        [legend]="false"
-        [showXAxisLabel]="false"
-        [showYAxisLabel]="false"
-        [ngStyle]="{ fill: backgroundColor }"
-    >
-    </ngx-charts-bar-vertical>
+<div class="badge-outer">
+    <span class="badge badge-key">{{ key }}</span>
+    <span class="badge badge-value">{{ value }}</span>
 </div>
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.scss
 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.scss
similarity index 71%
copy from 
ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.scss
copy to 
ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.scss
index f399ceb4ca..f9f1f3fbd4 100644
--- 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.scss
+++ 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * 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.
@@ -16,10 +16,20 @@
  *
  */
 
-.mb-10 {
-    margin-bottom: 10px;
+.badge {
+    padding: 3px;
+    font-size: 10pt;
 }
 
-.mt--10 {
-    margin-top: -10px;
+.badge-key {
+    background: var(--color-accent);
+    color: var(--color-bg-0);
+    border-bottom-left-radius: 3px;
+    border-top-left-radius: 3px;
+}
+
+.badge-value {
+    background: var(--color-primary);
+    border-bottom-right-radius: 3px;
+    border-top-right-radius: 3px;
 }
diff --git 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements.component.ts
 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.ts
similarity index 71%
copy from 
ui/src/app/pipeline-details/components/elements/pipeline-elements.component.ts
copy to 
ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.ts
index e18cfdfb80..66cbdc8fe5 100644
--- 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements.component.ts
+++ 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component.ts
@@ -17,19 +17,16 @@
  */
 
 import { Component, Input } from '@angular/core';
-import { PipelineElementUnion } from '../../../editor/model/editor.model';
-import { Pipeline } from '@streampipes/platform-services';
 
 @Component({
-    selector: 'sp-pipeline-elements',
-    templateUrl: './pipeline-elements.component.html',
+    selector: 'sp-pipeline-element-statistics-badge',
+    templateUrl: './pipeline-element-statistics-badge.component.html',
+    styleUrls: ['./pipeline-element-statistics-badge.component.scss'],
 })
-export class PipelineElementsComponent {
+export class PipelineElementStatisticsBadgeComponent {
     @Input()
-    pipeline: Pipeline;
+    key: string;
 
     @Input()
-    selectedElement: PipelineElementUnion;
-
-    constructor() {}
+    value: number;
 }
diff --git 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements.component.html
 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.html
similarity index 56%
rename from 
ui/src/app/pipeline-details/components/elements/pipeline-elements.component.html
rename to 
ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.html
index 93dee2089f..4009b5e32e 100644
--- 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements.component.html
+++ 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.html
@@ -16,25 +16,26 @@
   ~
   -->
 
-<sp-basic-inner-panel panelTitle="Element Details">
-    <div style="max-height: 800px; overflow: auto">
-        <div *ngIf="selectedElement">
-            <div fxLayout="column" style="padding: 5px; padding-left: 10px">
-                <sp-pipeline-elements-row
-                    [pipeline]="pipeline"
-                    [element]="selectedElement"
-                ></sp-pipeline-elements-row>
-
-                <mat-divider></mat-divider>
-                <div style="margin-bottom: 15px"></div>
-            </div>
+<div class="statistics" *ngIf="metricsInfo">
+    <div fxLayout="row" fxLayoutGap="5px">
+        <div fxLayout="column" fxLayoutAlign="start center">
+            <sp-pipeline-element-statistics-badge
+                *ngFor="let info of metricsInfo.messagesIn | keyvalue"
+                key="in"
+                [value]="info.value.counter"
+            >
+            </sp-pipeline-element-statistics-badge>
         </div>
         <div
             fxLayout="column"
-            fxLayoutAlign="center center"
-            *ngIf="!selectedElement"
+            *ngIf="type !== PipelineElementType.DataSink"
+            fxLayoutAlign="end center"
         >
-            (select an element in the preview window to see details)
+            <sp-pipeline-element-statistics-badge
+                key="out"
+                [value]="metricsInfo.messagesOut.counter"
+            >
+            </sp-pipeline-element-statistics-badge>
         </div>
     </div>
-</sp-basic-inner-panel>
+</div>
diff --git a/ui/src/app/pipeline-details/pipeline-details.routes.ts 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.scss
similarity index 73%
rename from ui/src/app/pipeline-details/pipeline-details.routes.ts
rename to 
ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.scss
index ac5ebcb735..581ac2cbd8 100644
--- a/ui/src/app/pipeline-details/pipeline-details.routes.ts
+++ 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.scss
@@ -16,11 +16,23 @@
  *
  */
 
-import { SpBreadcrumbItem } from '@streampipes/shared-ui';
+.mb-10 {
+    margin-bottom: 10px;
+}
+
+.mt--10 {
+    margin-top: -10px;
+}
 
-export class SpPipelineDetailsRoutes {
-    static BASE: SpBreadcrumbItem = {
-        label: 'Pipeline Details',
-        link: ['pipelines'],
-    };
+.statistics {
+    position: relative;
+    left: -45px;
+    top: -35px;
+    height: 30px;
+    width: 180px;
+    overflow: hidden;
+    z-index: 50;
+    display: flex;
+    justify-content: center;
+    align-items: center;
 }
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.ts
 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.ts
similarity index 51%
rename from 
ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.ts
rename to 
ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.ts
index 81ea542d3b..bca6523ec3 100644
--- 
a/ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.ts
+++ 
b/ui/src/app/editor/components/pipeline-element-statistics/pipeline-element-statistics.component.ts
@@ -18,34 +18,38 @@
 
 import { Component, Input, OnInit } from '@angular/core';
 
+import { SpMetricsEntry } from '@streampipes/platform-services';
+import {
+    PipelineElementType,
+    PipelineElementUnion,
+} from '../../model/editor.model';
+import { PipelineElementTypeUtils } from '../../utils/editor.utils';
+
 @Component({
-    selector: 'sp-barchart-widget',
-    templateUrl: './barchart-widget.component.html',
-    styleUrls: ['./barchart-widget.component.scss'],
+    selector: 'sp-pipeline-element-statistics',
+    templateUrl: './pipeline-element-statistics.component.html',
+    styleUrls: ['./pipeline-element-statistics.component.scss'],
 })
-export class BarchartWidgetComponent implements OnInit {
-    _data = [];
-
+export class PipelineElementStatisticsComponent implements OnInit {
     @Input()
-    backgroundColor = '#cccccc';
+    pipelineElement: PipelineElementUnion;
 
-    @Input()
-    textColor = '#1b1464';
+    _metricsInfo: SpMetricsEntry;
 
-    colorScheme = {
-        domain: ['#1b1464'],
-    };
+    type: PipelineElementType;
 
-    ngOnInit(): void {
-        this.colorScheme.domain = [this.textColor];
+    ngOnInit() {
+        this.type = PipelineElementTypeUtils.fromType(this.pipelineElement);
     }
 
-    @Input()
-    set data(data) {
-        this._data = data;
+    get metricsInfo() {
+        return this._metricsInfo;
     }
 
-    get data() {
-        return this._data;
+    @Input()
+    set metricsInfo(metricsInfo: SpMetricsEntry) {
+        this._metricsInfo = metricsInfo;
     }
+
+    protected readonly PipelineElementType = PipelineElementType;
 }
diff --git 
a/ui/src/app/editor/components/pipeline-element/pipeline-element.component.html 
b/ui/src/app/editor/components/pipeline-element/pipeline-element.component.html
index 0ef40b4a24..7771970c10 100644
--- 
a/ui/src/app/editor/components/pipeline-element/pipeline-element.component.html
+++ 
b/ui/src/app/editor/components/pipeline-element/pipeline-element.component.html
@@ -19,7 +19,7 @@
 <img [src]="image" *ngIf="showImage" style="{{ iconSizeCss() }}" />
 <span
     *ngIf="!showImage"
-    [ngClass]="iconStandSize ? 'text-small<' : 'element-text-icon'"
+    [ngClass]="iconStandSize ? 'text-small' : 'element-text-icon'"
 >
     {{ iconText }}
 </span>
diff --git 
a/ui/src/app/editor/components/pipeline-element/pipeline-element.component.ts 
b/ui/src/app/editor/components/pipeline-element/pipeline-element.component.ts
index 16801c26cc..f6c9c7c8d7 100644
--- 
a/ui/src/app/editor/components/pipeline-element/pipeline-element.component.ts
+++ 
b/ui/src/app/editor/components/pipeline-element/pipeline-element.component.ts
@@ -33,9 +33,6 @@ export class PipelineElementComponent {
 
     pipelineElement_: PipelineElementUnion;
 
-    @Input()
-    preview: any;
-
     @Input()
     iconSize: any;
 
@@ -72,8 +69,6 @@ export class PipelineElementComponent {
     iconSizeCss() {
         if (this.iconSize) {
             return 'width:35px;height:35px;';
-        } else if (this.preview) {
-            return 'width:50px;height:50px;';
         } else if (this.iconStandSize) {
             return 'width:30px;height:30px;';
         } else {
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.html 
b/ui/src/app/editor/components/pipeline/pipeline.component.html
index d1015b310f..53039821f5 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.html
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.html
@@ -68,9 +68,14 @@
         </div>
         <sp-pipeline-element
             [pipelineElement]="pipelineElement.payload"
-            [preview]="preview"
         ></sp-pipeline-element>
     </div>
+    <sp-pipeline-element-statistics
+        *ngIf="metricsInfo"
+        [pipelineElement]="pipelineElement.payload"
+        [metricsInfo]="metricsInfo[pipelineElement.payload.elementId]"
+    >
+    </sp-pipeline-element-statistics>
     <sp-pipeline-element-options
         *ngIf="!preview"
         (delete)="handleDeleteOption($event)"
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.ts 
b/ui/src/app/editor/components/pipeline/pipeline.component.ts
index 6838fff3cd..0dcb022857 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.ts
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.ts
@@ -48,6 +48,7 @@ import {
     PipelineModificationMessage,
     PipelinePreviewModel,
     SpDataStream,
+    SpMetricsEntry,
 } from '@streampipes/platform-services';
 import { ObjectProvider } from '../../services/object-provider.service';
 import { CustomizeComponent } from 
'../../dialog/customize/customize.component';
@@ -107,6 +108,9 @@ export class PipelineComponent implements OnInit, OnDestroy 
{
     @Input()
     pipelineCanvasMetadata: PipelineCanvasMetadata;
 
+    @Input()
+    metricsInfo: Record<string, SpMetricsEntry>;
+
     @Output()
     pipelineCacheRunningChanged: EventEmitter<boolean> =
         new EventEmitter<boolean>();
@@ -192,8 +196,8 @@ export class PipelineComponent implements OnInit, OnDestroy 
{
     getElementCss(currentPipelineElementSettings) {
         return (
             'position:absolute;' +
-            (this.preview ? 'width:75px;' : 'width:90px;') +
-            (this.preview ? 'height:75px;' : 'height:90px;') +
+            (this.preview ? 'width:90px;' : 'width:90px;') +
+            (this.preview ? 'height:90px;' : 'height:90px;') +
             'left: ' +
             currentPipelineElementSettings.position.x +
             'px; ' +
@@ -227,17 +231,6 @@ export class PipelineComponent implements OnInit, 
OnDestroy {
         );
     }
 
-    showMixedStreamAlert() {
-        this.dialog.open(ConfirmDialogComponent, {
-            width: '500px',
-            data: {
-                title: 'Currently, it is not possible to mix data streams and 
data sets in a single pipeline.',
-                confirmAndCancel: false,
-                okTitle: 'Ok',
-            },
-        });
-    }
-
     findPipelineElementByElementId(elementId: string) {
         return this.allElements.find(a => a.elementId === elementId);
     }
@@ -266,42 +259,34 @@ export class PipelineComponent implements OnInit, 
OnDestroy {
                             false,
                             newElementId,
                         );
-                    if (
-                        (this.isStreamInPipeline() &&
-                            pipelineElementConfig.type === 'set') ||
-                        (this.isSetInPipeline() &&
-                            pipelineElementConfig.type === 'stream')
-                    ) {
-                        this.showMixedStreamAlert();
-                    } else {
-                        this.rawPipelineModel.push(pipelineElementConfig);
-
-                        if (pipelineElementConfig.type === 'stream') {
-                            this.checkTopicModel(pipelineElementConfig);
-                        } else if (pipelineElementConfig.type === 'sepa') {
-                            setTimeout(() => {
-                                this.jsplumbService.dataProcessorDropped(
-                                    pipelineElementConfig.payload.dom,
-                                    pipelineElementConfig.payload as 
DataProcessorInvocation,
-                                    true,
-                                    false,
-                                );
-                            }, 10);
-                        } else if (pipelineElementConfig.type === 'action') {
-                            setTimeout(() => {
-                                this.jsplumbService.dataSinkDropped(
-                                    pipelineElementConfig.payload.dom,
-                                    pipelineElementConfig.payload as 
DataSinkInvocation,
-                                    true,
-                                    false,
-                                );
-                            }, 10);
-                        }
-                        if (this.shepherdService.isTourActive()) {
-                            this.shepherdService.trigger(
-                                'drop-' + pipelineElementConfig.type,
+
+                    this.rawPipelineModel.push(pipelineElementConfig);
+
+                    if (pipelineElementConfig.type === 'stream') {
+                        this.checkTopicModel(pipelineElementConfig);
+                    } else if (pipelineElementConfig.type === 'sepa') {
+                        setTimeout(() => {
+                            this.jsplumbService.dataProcessorDropped(
+                                pipelineElementConfig.payload.dom,
+                                pipelineElementConfig.payload as 
DataProcessorInvocation,
+                                true,
+                                false,
                             );
-                        }
+                        }, 10);
+                    } else if (pipelineElementConfig.type === 'action') {
+                        setTimeout(() => {
+                            this.jsplumbService.dataSinkDropped(
+                                pipelineElementConfig.payload.dom,
+                                pipelineElementConfig.payload as 
DataSinkInvocation,
+                                true,
+                                false,
+                            );
+                        }, 10);
+                    }
+                    if (this.shepherdService.isTourActive()) {
+                        this.shepherdService.trigger(
+                            'drop-' + pipelineElementConfig.type,
+                        );
                     }
                 }
                 this.JsplumbBridge.repaintEverything();
diff --git a/ui/src/app/editor/editor.module.ts 
b/ui/src/app/editor/editor.module.ts
index f1d0090ee2..32a6f823c6 100644
--- a/ui/src/app/editor/editor.module.ts
+++ b/ui/src/app/editor/editor.module.ts
@@ -74,6 +74,8 @@ import { MatProgressBarModule } from 
'@angular/material/progress-bar';
 import { MatButtonToggleModule } from '@angular/material/button-toggle';
 import { MatChipsModule } from '@angular/material/chips';
 import { MatSliderModule } from '@angular/material/slider';
+import { PipelineElementStatisticsComponent } from 
'./components/pipeline-element-statistics/pipeline-element-statistics.component';
+import { PipelineElementStatisticsBadgeComponent } from 
'./components/pipeline-element-statistics/pipeline-element-statistics-badge/pipeline-element-statistics-badge.component';
 import { SavePipelineSettingsComponent } from 
'./dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component';
 
 @NgModule({
@@ -135,6 +137,8 @@ import { SavePipelineSettingsComponent } from 
'./dialog/save-pipeline/save-pipel
         PipelineElementOptionsComponent,
         PipelineElementPreviewComponent,
         PipelineElementRecommendationComponent,
+        PipelineElementStatisticsComponent,
+        PipelineElementStatisticsBadgeComponent,
         PipelineElementTypeFilterPipe,
         PipelineComponent,
         PropertySelectionComponent,
diff --git a/ui/src/app/editor/model/editor.model.ts 
b/ui/src/app/editor/model/editor.model.ts
index 54c2ba151e..93e05eb084 100644
--- a/ui/src/app/editor/model/editor.model.ts
+++ b/ui/src/app/editor/model/editor.model.ts
@@ -43,7 +43,6 @@ export enum PipelineElementConfigurationStatus {
 export interface PipelineElementConfig {
     type: string;
     settings: {
-        preview: boolean;
         displaySettings: string;
         connectable: string;
         disabled: boolean;
diff --git a/ui/src/app/editor/services/jsplumb-config.service.ts 
b/ui/src/app/editor/services/jsplumb-config.service.ts
index ffac26a9d6..9795df34b3 100644
--- a/ui/src/app/editor/services/jsplumb-config.service.ts
+++ b/ui/src/app/editor/services/jsplumb-config.service.ts
@@ -32,10 +32,6 @@ export class JsplumbConfigService {
         return this.makeConfig(this.makeSettings(12, 5, 30, 30, 2, 80));
     }
 
-    getPreviewConfig() {
-        return this.makeConfig(this.makeSettings(6, 2, 15, 15, 1, 40));
-    }
-
     getEndpointTypeConfig(): Record<string, EndpointTypeDescriptor> {
         return {
             empty: {
diff --git a/ui/src/app/editor/services/jsplumb-endpoint.service.ts 
b/ui/src/app/editor/services/jsplumb-endpoint.service.ts
index 01b3ac5740..31e0438ef0 100644
--- a/ui/src/app/editor/services/jsplumb-endpoint.service.ts
+++ b/ui/src/app/editor/services/jsplumb-endpoint.service.ts
@@ -23,39 +23,33 @@ import { JsplumbConfigService } from 
'./jsplumb-config.service';
 export class JsplumbEndpointService {
     constructor(private jsplumbConfigService: JsplumbConfigService) {}
 
-    getJsplumbConfig(preview): any {
-        return preview
-            ? this.jsplumbConfigService.getPreviewConfig()
-            : this.jsplumbConfigService.getEditorConfig();
+    getJsplumbConfig(): any {
+        return this.jsplumbConfigService.getEditorConfig();
     }
 
-    getStreamEndpoint(preview: boolean, pipelineElementDomId: string) {
-        const jsplumbConfig = this.getJsplumbConfig(preview);
+    getStreamEndpoint(pipelineElementDomId: string) {
+        const jsplumbConfig = this.getJsplumbConfig();
         const config = jsplumbConfig.streamEndpointOptions;
         config.uuid = 'out-' + pipelineElementDomId;
         return config;
     }
 
-    getInputEndpoint(preview, pipelineElementDomId, index): any {
-        const jsplumbConfig = this.getJsplumbConfig(preview);
+    getInputEndpoint(pipelineElementDomId: string, index): any {
+        const jsplumbConfig = this.getJsplumbConfig();
         const inConfig = jsplumbConfig.leftTargetPointOptions;
         inConfig.uuid = 'in-' + index + '-' + pipelineElementDomId;
         return inConfig;
     }
 
-    getOutputEndpoint(preview, pipelineElementDomId): any {
-        const jsplumbConfig = this.getJsplumbConfig(preview);
+    getOutputEndpoint(pipelineElementDomId: string): any {
+        const jsplumbConfig = this.getJsplumbConfig();
         const outConfig = jsplumbConfig.sepaEndpointOptions;
         outConfig.uuid = 'out-' + pipelineElementDomId;
         return outConfig;
     }
 
-    getNewTargetPoint(preview, x, y, pipelineElementDomId, index): any {
-        const inConfig = this.getInputEndpoint(
-            preview,
-            pipelineElementDomId,
-            index,
-        );
+    getNewTargetPoint(x, y, pipelineElementDomId: string, index): any {
+        const inConfig = this.getInputEndpoint(pipelineElementDomId, index);
         inConfig.type = 'empty';
         inConfig.anchor = [x, y, -1, 0];
         inConfig.isTarget = true;
diff --git a/ui/src/app/editor/services/jsplumb.service.ts 
b/ui/src/app/editor/services/jsplumb.service.ts
index f0a61813a2..890018531a 100644
--- a/ui/src/app/editor/services/jsplumb.service.ts
+++ b/ui/src/app/editor/services/jsplumb.service.ts
@@ -182,8 +182,7 @@ export class JsplumbService {
     ) {
         const sourceElement = sourceElementSelector.get()[0];
         const jsplumbBridge = this.getBridge(previewConfig);
-        const jsplumbConfig =
-            this.jsplumbEndpointService.getJsplumbConfig(true);
+        const jsplumbConfig = this.jsplumbEndpointService.getJsplumbConfig();
         const options = sourceElementSelector.hasClass('stream')
             ? jsplumbConfig.streamEndpointOptions
             : jsplumbConfig.sepaEndpointOptions;
@@ -252,9 +251,7 @@ export class JsplumbService {
         isCompleted: boolean,
         newElementId?: string,
     ): PipelineElementConfig {
-        const displaySettings = isPreview
-            ? 'connectable-preview'
-            : 'connectable-editor';
+        const displaySettings = 'connectable-editor';
         const connectable = 'connectable';
         const pipelineElementConfig = {} as PipelineElementConfig;
         pipelineElementConfig.type = PipelineElementTypeUtils.toCssShortHand(
@@ -266,7 +263,6 @@ export class JsplumbService {
         );
         pipelineElementConfig.settings = {
             connectable,
-            preview: isPreview,
             completed:
                 pipelineElement instanceof SpDataStream ||
                 isPreview ||
@@ -368,7 +364,6 @@ export class JsplumbService {
         if (endpoints) {
             const endpointOptions =
                 this.jsplumbEndpointService.getStreamEndpoint(
-                    preview,
                     pipelineElementDomId,
                 );
             jsplumbBridge.addEndpoint(pipelineElementDomId, endpointOptions);
@@ -393,7 +388,6 @@ export class JsplumbService {
             jsplumbBridge.addEndpoint(
                 pipelineElementDomId,
                 this.jsplumbEndpointService.getOutputEndpoint(
-                    preview,
                     pipelineElementDomId,
                 ),
             );
@@ -414,7 +408,6 @@ export class JsplumbService {
                 jsplumbBridge.addEndpoint(
                     pipelineElementDomId,
                     this.jsplumbEndpointService.getInputEndpoint(
-                        preview,
                         pipelineElementDomId,
                         0,
                     ),
@@ -423,7 +416,6 @@ export class JsplumbService {
                 jsplumbBridge.addEndpoint(
                     pipelineElementDomId,
                     this.jsplumbEndpointService.getNewTargetPoint(
-                        preview,
                         0,
                         0.3,
                         pipelineElementDomId,
@@ -433,7 +425,6 @@ export class JsplumbService {
                 jsplumbBridge.addEndpoint(
                     pipelineElementDomId,
                     this.jsplumbEndpointService.getNewTargetPoint(
-                        preview,
                         0,
                         0.7,
                         pipelineElementDomId,
diff --git a/ui/src/app/editor/services/pipeline-positioning.service.ts 
b/ui/src/app/editor/services/pipeline-positioning.service.ts
index d4949efbc0..1565101c72 100644
--- a/ui/src/app/editor/services/pipeline-positioning.service.ts
+++ b/ui/src/app/editor/services/pipeline-positioning.service.ts
@@ -87,9 +87,7 @@ export class PipelinePositioningService {
         const jsPlumbBridge =
             this.jsplumbFactoryService.getJsplumbBridge(previewConfig);
 
-        const jsplumbConfig = previewConfig
-            ? this.jsplumbConfigService.getPreviewConfig()
-            : this.jsplumbConfigService.getEditorConfig();
+        const jsplumbConfig = this.jsplumbConfigService.getEditorConfig();
 
         rawPipelineModel.forEach(currentPe => {
             if (!currentPe.settings.disabled) {
@@ -123,14 +121,13 @@ export class PipelinePositioningService {
         this.connectPipelineElements(
             rawPipelineModel,
             previewConfig,
-            jsplumbConfig,
             jsPlumbBridge,
         );
         if (autoLayout) {
             this.layoutGraph(
                 targetCanvas,
                 "div[id^='jsplumb']",
-                previewConfig ? 75 : 110,
+                110,
                 previewConfig,
             );
         } else if (pipelineCanvasMetadata) {
@@ -148,7 +145,7 @@ export class PipelinePositioningService {
         const jsPlumbBridge =
             this.jsplumbFactoryService.getJsplumbBridge(previewConfig);
         const g = new dagre.graphlib.Graph();
-        g.setGraph({ rankdir: 'LR', ranksep: previewConfig ? '50' : '100' });
+        g.setGraph({ rankdir: 'LR', ranksep: '100' });
         g.setDefaultEdgeLabel(() => {
             return {};
         });
@@ -191,18 +188,13 @@ export class PipelinePositioningService {
     connectPipelineElements(
         rawPipelineModel: PipelineElementConfig[],
         previewConfig: boolean,
-        jsplumbConfig: any,
         jsPlumbBridge: JsplumbBridge,
     ) {
-        let source;
-        let target;
         jsPlumbBridge.setSuspendDrawing(true);
         rawPipelineModel.forEach(pe => {
             if (pe.type === 'sepa' || pe.type === 'action') {
                 if (!pe.settings.disabled && pe.payload.connectedTo) {
                     pe.payload.connectedTo.forEach((connection, index) => {
-                        source = connection;
-                        target = pe.payload.dom;
                         const sourceEndpointId = 'out-' + connection;
                         const inTargetEndpointId =
                             'in-' + index + '-' + pe.payload.dom;
diff --git 
a/ui/src/app/pipeline-details/components/actions/pipeline-actions.component.html
 
b/ui/src/app/pipeline-details/components/actions/pipeline-actions.component.html
deleted file mode 100644
index 447a49f07f..0000000000
--- 
a/ui/src/app/pipeline-details/components/actions/pipeline-actions.component.html
+++ /dev/null
@@ -1,89 +0,0 @@
-<!--
-  ~ 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.
-  ~
-  -->
-
-<sp-basic-inner-panel panelTitle="Actions">
-    <div
-        fxFlex="100"
-        fxLayoutAlign="center center"
-        fxLayout="row"
-        style="padding: 10px"
-    >
-        <div fxFlex="30">
-            <button
-                mat-button
-                mat-raised-button
-                color="accent"
-                matTooltip="Start Pipeline"
-                matTooltipPosition="above"
-                (click)="startPipeline()"
-                [disabled]="starting"
-                *ngIf="!pipeline.running"
-            >
-                <mat-icon>play_arrow</mat-icon>
-                <span>&nbsp;Start</span>
-            </button>
-            <button
-                mat-button
-                mat-raised-button
-                color="accent"
-                matTooltip="Stop Pipeline"
-                matTooltipPosition="above"
-                (click)="stopPipeline()"
-                [disabled]="stopping"
-                *ngIf="pipeline.running"
-            >
-                <mat-icon>stop</mat-icon>
-                <span>&nbsp;Stop</span>
-            </button>
-        </div>
-        <div fxFlex="30">
-            <button
-                mat-button
-                mat-raised-button
-                color="accent"
-                matTooltip="Modify Pipeline"
-                matTooltipPosition="above"
-                [disabled]="pipeline.running"
-                
(click)="pipelineOperationsService.modifyPipeline(pipeline._id)"
-            >
-                <mat-icon>mode_edit</mat-icon>
-                <span>&nbsp;Modify</span>
-            </button>
-        </div>
-        <div fxFlex="30">
-            <button
-                mat-button
-                mat-raised-button
-                color="accent"
-                matTooltip="Delete Pipeline"
-                matTooltipPosition="above"
-                *ngIf="hasPipelineDeletePrivileges"
-                (click)="
-                    pipelineOperationsService.showDeleteDialog(
-                        pipeline,
-                        reloadPipelineEmitter,
-                        this.switchToPipelineView
-                    )
-                "
-            >
-                <mat-icon>delete</mat-icon>
-                <span>&nbsp;Delete</span>
-            </button>
-        </div>
-    </div>
-</sp-basic-inner-panel>
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.html
 
b/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.html
deleted file mode 100644
index 2bf5a29a66..0000000000
--- 
a/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.html
+++ /dev/null
@@ -1,113 +0,0 @@
-<!--
-  ~ 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.
-  ~
-  -->
-
-<sp-basic-nav-tabs
-    [spNavigationItems]="tabs"
-    [activeLink]="'monitoring'"
-    [showBackLink]="true"
-    [backLinkTarget]="['pipelines']"
->
-    <div nav fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
-        <button
-            mat-icon-button
-            color="accent"
-            class="mr-10"
-            matTooltip="Refresh"
-            (click)="triggerMetricsUpdate()"
-        >
-            <i class="material-icons">refresh</i>
-        </button>
-        <mat-slide-toggle [(ngModel)]="autoRefresh" color="accent"
-            >Auto refresh</mat-slide-toggle
-        >
-    </div>
-    <div fxLayout="column" class="page-container-padding" *ngIf="pipeline">
-        <div
-            fxFlex="100"
-            fxLayout="column"
-            class="page-container-padding-inner"
-        >
-            <div
-                fxFlex="100"
-                *ngIf="!pipeline.running"
-                fxLayout="column"
-                fxLayoutAlign="center center"
-            >
-                <div class="error-message">
-                    (monitoring info is only available for running pipelines)
-                </div>
-                <button
-                    mat-button
-                    mat-raised-button
-                    color="accent"
-                    matTooltip="Start Pipeline"
-                    matTooltipPosition="above"
-                    *ngIf="hasPipelineWritePrivileges"
-                    (click)="startPipeline()"
-                >
-                    <mat-icon>play_arrow</mat-icon>
-                    <span>&nbsp;Start pipeline</span>
-                </button>
-            </div>
-            <div
-                fxFlex="100"
-                *ngIf="pipeline.running && pipelineMonitoringInfoAvailable"
-            >
-                <sp-pipeline-preview
-                    [jspcanvas]="'assembly-preview'"
-                    [pipeline]="pipeline"
-                    (selectedElementEmitter)="selectElement($event)"
-                    style="margin-bottom: 15px"
-                    class="md-padding"
-                    *ngIf="pipelineAvailable"
-                ></sp-pipeline-preview>
-                <div
-                    *ngFor="let pipelineElement of monitoredElements"
-                    fxLayout="column"
-                    class="mb-10 mt-10"
-                >
-                    <sp-basic-inner-panel
-                        [panelTitle]="pipelineElement.name"
-                        [id]="pipelineElement.elementId"
-                    >
-                        <div fxFlex="100" fxLayout="row">
-                            <div fxFlex="20" fxLayoutAlign="start start">
-                                <sp-pipeline-elements-row
-                                    style="width: 100%"
-                                    [showDescription]="false"
-                                    [pipeline]="pipeline"
-                                    [element]="pipelineElement"
-                                ></sp-pipeline-elements-row>
-                            </div>
-                            <div fxFlex="80" fxLayoutAlign="start center">
-                                <sp-pipeline-element-statistics
-                                    [allElements]="allElements"
-                                    [pipelineElement]="pipelineElement"
-                                    [metricsInfo]="
-                                        metricsInfo[pipelineElement.elementId]
-                                    "
-                                >
-                                </sp-pipeline-element-statistics>
-                            </div>
-                        </div>
-                    </sp-basic-inner-panel>
-                </div>
-            </div>
-        </div>
-    </div>
-</sp-basic-nav-tabs>
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.ts
 
b/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.ts
deleted file mode 100644
index f7fee8242c..0000000000
--- 
a/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.ts
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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.
- *
- */
-
-import { Component, EventEmitter, OnDestroy, OnInit } from '@angular/core';
-import {
-    DataProcessorInvocation,
-    DataSinkInvocation,
-    PipelineMonitoringInfo,
-    PipelineMonitoringService,
-    PipelineService,
-    SpDataStream,
-    SpMetricsEntry,
-} from '@streampipes/platform-services';
-import { PipelineOperationsService } from 
'../../../pipelines/services/pipeline-operations.service';
-import { AuthService } from '../../../services/auth.service';
-import { SpPipelineDetailsDirective } from '../sp-pipeline-details.directive';
-import { ActivatedRoute } from '@angular/router';
-import { Subscription } from 'rxjs';
-import {
-    CurrentUserService,
-    SpBreadcrumbService,
-} from '@streampipes/shared-ui';
-import { SpPipelineRoutes } from '../../../pipelines/pipelines.routes';
-
-@Component({
-    selector: 'sp-pipeline-monitoring',
-    templateUrl: './pipeline-monitoring.component.html',
-    styleUrls: ['./pipeline-monitoring.component.scss'],
-})
-export class PipelineMonitoringComponent
-    extends SpPipelineDetailsDirective
-    implements OnInit, OnDestroy
-{
-    pipelineMonitoringInfo: PipelineMonitoringInfo;
-    pipelineMonitoringInfoAvailable = false;
-
-    allElements: (
-        | SpDataStream
-        | DataProcessorInvocation
-        | DataSinkInvocation
-    )[] = [];
-    monitoredElements: (DataProcessorInvocation | DataSinkInvocation)[] = [];
-
-    autoRefresh = true;
-
-    metricsInfo: Record<string, SpMetricsEntry>;
-
-    reloadPipelinesEmitter: EventEmitter<boolean> = new 
EventEmitter<boolean>();
-    reloadSubscription: Subscription;
-
-    constructor(
-        activatedRoute: ActivatedRoute,
-        pipelineService: PipelineService,
-        authService: AuthService,
-        currentUserService: CurrentUserService,
-        private pipelineMonitoringService: PipelineMonitoringService,
-        private pipelineOperationsService: PipelineOperationsService,
-        breadcrumbService: SpBreadcrumbService,
-    ) {
-        super(
-            activatedRoute,
-            pipelineService,
-            authService,
-            currentUserService,
-            breadcrumbService,
-        );
-    }
-
-    ngOnInit(): void {
-        super.onInit();
-        this.reloadSubscription = this.reloadPipelinesEmitter.subscribe(
-            reload => this.loadPipeline(),
-        );
-    }
-
-    checkMonitoringInfoCollection() {
-        if (this.pipeline.running) {
-            this.refreshMonitoringInfo();
-        }
-    }
-
-    collectAllElements() {
-        this.monitoredElements = this.monitoredElements
-            .concat(this.pipeline.sepas)
-            .concat(this.pipeline.actions);
-
-        this.allElements = this.allElements
-            .concat(this.monitoredElements)
-            .concat(this.pipeline.streams);
-    }
-
-    refreshMonitoringInfo(addTimeout = true) {
-        this.pipelineMonitoringService
-            .getMetricsInfoForPipeline(this.pipeline._id)
-            .subscribe(monitoringInfo => {
-                this.metricsInfo = monitoringInfo;
-                this.pipelineMonitoringInfoAvailable = true;
-                if (this.autoRefresh && addTimeout) {
-                    setTimeout(() => {
-                        this.refreshMonitoringInfo();
-                    }, 5000);
-                }
-            });
-    }
-
-    selectElement(pipelineElement) {
-        document.getElementById(pipelineElement.elementId).scrollIntoView();
-    }
-
-    ngOnDestroy(): void {
-        this.autoRefresh = false;
-        this.reloadSubscription.unsubscribe();
-    }
-
-    startPipeline() {
-        this.pipelineOperationsService.startPipeline(
-            this.pipeline._id,
-            this.reloadPipelinesEmitter,
-        );
-    }
-
-    onPipelineAvailable(): void {
-        this.breadcrumbService.updateBreadcrumb([
-            SpPipelineRoutes.BASE,
-            { label: this.pipeline.name },
-            { label: 'Metrics' },
-        ]);
-        this.collectAllElements();
-        this.refreshMonitoringInfo();
-    }
-
-    triggerMetricsUpdate(): void {
-        this.pipelineMonitoringService
-            .triggerMonitoringUpdate()
-            .subscribe(res => {
-                this.refreshMonitoringInfo(false);
-            });
-    }
-}
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.html
 
b/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.html
deleted file mode 100644
index 99060176ca..0000000000
--- 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
-  ~ 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 fxFlex="100" fxLayout="row" fxLayoutAlign="start start">
-    <div *ngIf="observedInputStreams.length > 0">
-        <div
-            [fxFlex]="70 / observedInputStreams.length"
-            *ngFor="let observedInputStream of observedInputStreams"
-        >
-            <div fxLayout="column" class="mb-10">
-                <sp-status-widget
-                    fxFlex="100"
-                    [label]="
-                        'consumed from ' +
-                        observedInputStream.pipelineElementName
-                    "
-                    [color]="
-                        consumedMessagesFirstInputStream === notAvailable
-                            ? deactivatedCardColor
-                            : cardColor
-                    "
-                    [textColor]="
-                        consumedMessagesFirstInputStream === notAvailable
-                            ? deactivatedTextColor
-                            : textColor
-                    "
-                    [statusValue]="
-                        metricsInfo.messagesIn[observedInputStream.identifier]
-                            ? metricsInfo.messagesIn[
-                                  observedInputStream.identifier
-                              ].counter
-                            : '0'
-                    "
-                >
-                </sp-status-widget>
-            </div>
-        </div>
-    </div>
-    <div fxFlex="30">
-        <div fxLayout="column" class="mb-10" *ngIf="!dataSink">
-            <sp-status-widget
-                fxFlex="100"
-                [label]="'produced messages'"
-                [color]="
-                    producedMessages === notAvailable
-                        ? deactivatedCardColor
-                        : cardColor
-                "
-                [textColor]="
-                    producedMessages === notAvailable
-                        ? deactivatedTextColor
-                        : textColor
-                "
-                [statusValue]="metricsInfo.messagesOut.counter"
-            ></sp-status-widget>
-        </div>
-    </div>
-</div>
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.ts
 
b/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.ts
deleted file mode 100644
index 7f274deb41..0000000000
--- 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.
- *
- */
-
-import { Component, Input, OnInit } from '@angular/core';
-
-import {
-    DataProcessorInvocation,
-    DataSinkInvocation,
-    SpDataStream,
-    SpMetricsEntry,
-} from '@streampipes/platform-services';
-import {
-    HistoricalMonitoringData,
-    ObservedMetricsStream,
-} from '../../model/pipeline-details.model';
-
-@Component({
-    selector: 'sp-pipeline-element-statistics',
-    templateUrl: './pipeline-element-statistics.component.html',
-    styleUrls: ['./pipeline-element-statistics.component.scss'],
-})
-export class PipelineElementStatisticsComponent implements OnInit {
-    @Input()
-    allElements: (
-        | SpDataStream
-        | DataProcessorInvocation
-        | DataSinkInvocation
-    )[];
-
-    @Input()
-    pipelineElement:
-        | SpDataStream
-        | DataProcessorInvocation
-        | DataSinkInvocation;
-
-    _metricsInfo: SpMetricsEntry;
-
-    currentPipelineElement:
-        | SpDataStream
-        | DataProcessorInvocation
-        | DataSinkInvocation;
-    consumedMessagesFirstInputStream = '';
-    consumedMessagesSecondInputStream = '';
-
-    producedMessages: string | number = '';
-
-    cardColor = 'rgb(27, 20, 100)';
-    deactivatedCardColor = 'rgb(241,241,241)';
-
-    textColor = 'rgb(208,208,208)';
-    deactivatedTextColor = 'rgb(205,205,205)';
-
-    bandColor = 'rgb(27, 20, 100)';
-    deactivatedBandColor = 'rgb(241,241,241)';
-    okBandColor = 'rgb(11,186,0)';
-    warningBandColor = 'rgb(253,144,0)';
-
-    chartBackgroundColor = 'rgb(27, 20, 100)';
-    chartTextColor = 'rgb(208,208,208)';
-
-    consumedMessagesFirstStreamBandColor: string;
-    consumedMessagesSecondStreamBandColor: string;
-
-    notAvailable = '-';
-
-    historicFirstConsumedInputValues: HistoricalMonitoringData[] = [];
-    historicSecondConsumedInputValues: HistoricalMonitoringData[] = [];
-    historicProducedOutputValues: HistoricalMonitoringData[] = [];
-
-    consumedMessagesFirstStreamLastValue = -1;
-    consumedMessagesSecondStreamLastValue = -1;
-    producedMessageOutputLastValue = -1;
-
-    consumedMessagesFirstStreamAvailable = false;
-    consumedMessagesSecondStreamAvailable = false;
-    producedMessagesAvailable = false;
-
-    observedInputStreams: ObservedMetricsStream[] = [];
-    dataSink = false;
-
-    ngOnInit(): void {
-        this.dataSink = this.pipelineElement instanceof DataSinkInvocation;
-        if (
-            this.pipelineElement instanceof DataSinkInvocation ||
-            this.pipelineElement instanceof DataProcessorInvocation
-        ) {
-            this.pipelineElement.inputStreams.forEach(is => {
-                const identifier =
-                    is.eventGrounding.transportProtocols[0].topicDefinition
-                        .actualTopicName;
-                this.observedInputStreams.push({
-                    pipelineElementName: this.extractName(identifier),
-                    identifier,
-                });
-            });
-        }
-    }
-
-    extractName(outputTopic: string): string {
-        return this.allElements
-            .filter(el => !(el instanceof DataSinkInvocation))
-            .find(el => {
-                if (el instanceof DataProcessorInvocation) {
-                    return (
-                        el.outputStream.eventGrounding.transportProtocols[0]
-                            .topicDefinition.actualTopicName === outputTopic
-                    );
-                } else {
-                    return (
-                        (el as SpDataStream).eventGrounding
-                            .transportProtocols[0].topicDefinition
-                            .actualTopicName === outputTopic
-                    );
-                }
-            }).name;
-    }
-
-    updateMonitoringInfo() {}
-
-    get metricsInfo() {
-        return this._metricsInfo;
-    }
-
-    @Input()
-    set metricsInfo(metricsInfo: SpMetricsEntry) {
-        this._metricsInfo = metricsInfo;
-        this.updateMonitoringInfo();
-    }
-}
diff --git 
a/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.html
 
b/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.html
deleted file mode 100644
index 3fc70d8c71..0000000000
--- 
a/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!--
-  ~ 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.
-  ~
-  -->
-
-<sp-basic-nav-tabs
-    [spNavigationItems]="tabs"
-    [activeLink]="'overview'"
-    [showBackLink]="true"
-    [backLinkTarget]="['pipelines']"
->
-    <div fxLayout="column" class="page-container-padding">
-        <div fxFlex="100" fxLayout="column">
-            <sp-pipeline-preview
-                [jspcanvas]="'assembly-preview'"
-                [pipeline]="pipeline"
-                (selectedElementEmitter)="selectElement($event)"
-                style="margin-bottom: 15px"
-                class="md-padding"
-                *ngIf="pipelineAvailable"
-            ></sp-pipeline-preview>
-            <div
-                fxFlex
-                fxLayout="row"
-                fxLayoutAlign="start top"
-                *ngIf="pipelineAvailable"
-            >
-                <div fxFlex="60" class="md-padding">
-                    <div fxFlex fxLayout="column">
-                        <sp-pipeline-elements
-                            [pipeline]="pipeline"
-                            [selectedElement]="selectedElement"
-                        ></sp-pipeline-elements>
-                    </div>
-                </div>
-                <div fxFlex="40" class="md-padding">
-                    <div fxFlex fxLayout="column">
-                        <sp-pipeline-actions
-                            (reloadPipelineEmitter)="loadPipeline()"
-                            [pipeline]="pipeline"
-                            style="margin-bottom: 15px"
-                            *ngIf="hasPipelineWritePrivileges"
-                        ></sp-pipeline-actions>
-                        <sp-pipeline-status
-                            [pipeline]="pipeline"
-                        ></sp-pipeline-status>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</sp-basic-nav-tabs>
diff --git 
a/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.ts
 
b/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.ts
deleted file mode 100644
index 4e5e124703..0000000000
--- 
a/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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.
- *
- */
-
-import { Component, OnInit } from '@angular/core';
-import { ActivatedRoute } from '@angular/router';
-import { SpPipelineDetailsDirective } from '../sp-pipeline-details.directive';
-import { AuthService } from '../../../services/auth.service';
-import { PipelineService } from '@streampipes/platform-services';
-import { PipelineElementUnion } from '../../../editor/model/editor.model';
-import {
-    CurrentUserService,
-    SpBreadcrumbService,
-} from '@streampipes/shared-ui';
-import { SpPipelineRoutes } from '../../../pipelines/pipelines.routes';
-
-@Component({
-    selector: 'sp-pipeline-details-overview-component',
-    templateUrl: './pipeline-details-overview.component.html',
-    styleUrls: ['./pipeline-details-overview.component.scss'],
-})
-export class SpPipelineDetailsOverviewComponent
-    extends SpPipelineDetailsDirective
-    implements OnInit
-{
-    tabs = [];
-    selectedElement: PipelineElementUnion;
-
-    constructor(
-        activatedRoute: ActivatedRoute,
-        pipelineService: PipelineService,
-        authService: AuthService,
-        currentUserService: CurrentUserService,
-        breadcrumbService: SpBreadcrumbService,
-    ) {
-        super(
-            activatedRoute,
-            pipelineService,
-            authService,
-            currentUserService,
-            breadcrumbService,
-        );
-    }
-
-    ngOnInit(): void {
-        super.onInit();
-    }
-
-    selectElement(element: PipelineElementUnion) {
-        this.selectedElement = element;
-    }
-
-    onPipelineAvailable(): void {
-        this.breadcrumbService.updateBreadcrumb([
-            SpPipelineRoutes.BASE,
-            { label: this.pipeline.name },
-            { label: 'Overview' },
-        ]);
-    }
-}
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/actions/pipeline-actions.component.html
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/actions/pipeline-actions.component.html
new file mode 100644
index 0000000000..3f60c319ad
--- /dev/null
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/actions/pipeline-actions.component.html
@@ -0,0 +1,83 @@
+<!--
+  ~ 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
+    fxFlex="100"
+    fxLayoutAlign="start start"
+    fxLayout="column"
+    style="padding: 10px"
+>
+    <div fxLayout="row" *ngIf="!pipeline.running" fxLayoutAlign="start center">
+        <button
+            mat-icon-button
+            color="accent"
+            matTooltip="Start Pipeline"
+            matTooltipPosition="above"
+            (click)="startPipeline()"
+            [disabled]="starting || !hasWritePipelinePrivileges"
+        >
+            <mat-icon>play_arrow</mat-icon>
+        </button>
+        <span>&nbsp;Start pipeline</span>
+    </div>
+    <div fxLayout="row" *ngIf="pipeline.running" fxLayoutAlign="start center">
+        <button
+            mat-icon-button
+            color="accent"
+            matTooltip="Stop Pipeline"
+            matTooltipPosition="above"
+            (click)="stopPipeline()"
+            [disabled]="stopping || !hasWritePipelinePrivileges"
+        >
+            <mat-icon>stop</mat-icon>
+        </button>
+        <span>&nbsp;Stop pipeline</span>
+    </div>
+    <div fxLayout="row" fxLayoutAlign="start center">
+        <button
+            mat-icon-button
+            color="accent"
+            matTooltip="Modify Pipeline"
+            matTooltipPosition="above"
+            [disabled]="!hasWritePipelinePrivileges"
+            (click)="pipelineOperationsService.modifyPipeline(pipeline._id)"
+        >
+            <mat-icon>mode_edit</mat-icon>
+        </button>
+        <span>&nbsp;Modify pipeline</span>
+    </div>
+    <div fxLayout="row" fxLayoutAlign="start center">
+        <button
+            mat-icon-button
+            color="accent"
+            matTooltip="Delete Pipeline"
+            matTooltipPosition="above"
+            [disabled]="!hasDeletePipelinePrivileges"
+            (click)="
+                pipelineOperationsService.showDeleteDialog(
+                    pipeline,
+                    reloadPipelineEmitter,
+                    this.switchToPipelineView
+                )
+            "
+        >
+            <mat-icon>delete</mat-icon>
+        </button>
+        <span>&nbsp;Delete pipeline</span>
+    </div>
+</div>
diff --git 
a/ui/src/app/pipeline-details/components/actions/pipeline-actions.component.ts 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/actions/pipeline-actions.component.ts
similarity index 78%
rename from 
ui/src/app/pipeline-details/components/actions/pipeline-actions.component.ts
rename to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/actions/pipeline-actions.component.ts
index 15f507e275..8b22521a6b 100644
--- 
a/ui/src/app/pipeline-details/components/actions/pipeline-actions.component.ts
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/actions/pipeline-actions.component.ts
@@ -17,12 +17,9 @@
  */
 
 import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
-import { PipelineOperationsService } from 
'../../../pipelines/services/pipeline-operations.service';
+import { PipelineOperationsService } from 
'../../../../pipelines/services/pipeline-operations.service';
 import { Pipeline } from '@streampipes/platform-services';
 import { Router } from '@angular/router';
-import { AuthService } from '../../../services/auth.service';
-import { UserPrivilege } from '../../../_enums/user-privilege.enum';
-import { CurrentUserService } from '@streampipes/shared-ui';
 
 @Component({
     selector: 'sp-pipeline-actions',
@@ -35,24 +32,21 @@ export class PipelineActionsComponent implements OnInit {
     @Input()
     pipeline: Pipeline;
 
+    @Input()
+    hasDeletePipelinePrivileges: boolean;
+
+    @Input()
+    hasWritePipelinePrivileges: boolean;
+
     @Output()
     reloadPipelineEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
 
-    hasPipelineDeletePrivileges = false;
-
     constructor(
         public pipelineOperationsService: PipelineOperationsService,
         private router: Router,
-        private authService: AuthService,
-        private currentUserService: CurrentUserService,
     ) {}
 
     ngOnInit() {
-        this.currentUserService.user$.subscribe(user => {
-            this.hasPipelineDeletePrivileges = this.authService.hasRole(
-                UserPrivilege.PRIVILEGE_DELETE_PIPELINE,
-            );
-        });
         this.toggleRunningOperation = this.toggleRunningOperation.bind(this);
         this.switchToPipelineView = this.switchToPipelineView.bind(this);
     }
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.html
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.html
new file mode 100644
index 0000000000..5a3dc3eb26
--- /dev/null
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.html
@@ -0,0 +1,56 @@
+<!--
+  ~ 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.
+  ~
+  -->
+
+<mat-accordion>
+    <mat-expansion-panel [(expanded)]="expanded">
+        <mat-expansion-panel-header class="expansion-panel-header">
+            Logs
+        </mat-expansion-panel-header>
+        <div fxLayout="column" fxFlex="100" class="p-10">
+            <div
+                *ngFor="let element of allPipelineElements"
+                class="details-row"
+            >
+                <sp-pipeline-element-details-row
+                    [pipelineElement]="element"
+                    [logInfo]="logInfo[element.elementId]"
+                    [pipelineRunning]="pipeline.running"
+                >
+                </sp-pipeline-element-details-row>
+            </div>
+        </div>
+    </mat-expansion-panel>
+    <mat-expansion-panel>
+        <mat-expansion-panel-header class="expansion-panel-header">
+            Status
+        </mat-expansion-panel-header>
+        <sp-pipeline-status [pipeline]="pipeline"> </sp-pipeline-status>
+    </mat-expansion-panel>
+    <mat-expansion-panel>
+        <mat-expansion-panel-header class="expansion-panel-header">
+            Actions
+        </mat-expansion-panel-header>
+        <sp-pipeline-actions
+            (reloadPipelineEmitter)="reloadPipelineEmitter.emit()"
+            [pipeline]="pipeline"
+            [hasWritePipelinePrivileges]="hasWritePipelinePrivileges"
+            [hasDeletePipelinePrivileges]="hasDeletePipelinePrivileges"
+        >
+        </sp-pipeline-actions>
+    </mat-expansion-panel>
+</mat-accordion>
diff --git 
a/ui/src/app/pipeline-details/components/model/pipeline-details.model.ts 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.scss
similarity index 78%
rename from 
ui/src/app/pipeline-details/components/model/pipeline-details.model.ts
rename to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.scss
index 98cda1dd3f..824e9b0109 100644
--- a/ui/src/app/pipeline-details/components/model/pipeline-details.model.ts
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * 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.
@@ -16,12 +16,16 @@
  *
  */
 
-export interface HistoricalMonitoringData {
-    name: string;
-    value: number;
+.expansion-panel-header {
+    font-weight: bold;
+    border-bottom: 1px solid var(--color-bg-2);
 }
 
-export interface ObservedMetricsStream {
-    pipelineElementName: string;
-    identifier: string;
+.details-row {
+    padding-top: 5px;
+    padding-bottom: 5px;
+}
+
+.details-row:hover {
+    background: var(--color-bg-2);
 }
diff --git 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.ts
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.ts
similarity index 51%
copy from 
ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.ts
copy to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.ts
index 016a0c2114..a5777ddda5 100644
--- 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.ts
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component.ts
@@ -16,45 +16,40 @@
  *
  */
 
-import { Component, Input, OnInit } from '@angular/core';
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
+import { Pipeline, SpLogEntry } from '@streampipes/platform-services';
 import { PipelineElementUnion } from '../../../editor/model/editor.model';
-import { Pipeline } from '@streampipes/platform-services';
-import { PipelineElementTypeUtils } from '../../../editor/utils/editor.utils';
 
 @Component({
-    selector: 'sp-pipeline-elements-row',
-    templateUrl: './pipeline-elements-row.component.html',
+    selector: 'sp-pipeline-details-expansion-panel',
+    templateUrl: './pipeline-details-expansion-panel.component.html',
+    styleUrls: ['./pipeline-details-expansion-panel.component.scss'],
 })
-export class PipelineElementsRowComponent implements OnInit {
-    elementType: string;
+export class PipelineDetailsExpansionPanelComponent implements OnInit {
+    expanded = true;
 
     @Input()
     pipeline: Pipeline;
 
     @Input()
-    showDescription = true;
+    logInfo: Record<string, SpLogEntry[]>;
 
-    _element: PipelineElementUnion;
+    @Input()
+    hasDeletePipelinePrivileges: boolean;
 
-    constructor() {}
+    @Input()
+    hasWritePipelinePrivileges: boolean;
 
-    ngOnInit() {
-        this.updateType();
-    }
+    @Output()
+    reloadPipelineEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
 
-    get element() {
-        return this._element;
-    }
-
-    @Input()
-    set element(element: PipelineElementUnion) {
-        this._element = element;
-        this.updateType();
-    }
+    allPipelineElements: PipelineElementUnion[] = [];
 
-    updateType() {
-        this.elementType = PipelineElementTypeUtils.toCssShortHand(
-            PipelineElementTypeUtils.fromType(this._element),
-        );
+    ngOnInit(): void {
+        this.allPipelineElements = [
+            ...this.pipeline.streams,
+            ...this.pipeline.sepas,
+            ...this.pipeline.actions,
+        ];
     }
 }
diff --git 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.html
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/elements/pipeline-elements-row.component.html
similarity index 60%
rename from 
ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.html
rename to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/elements/pipeline-elements-row.component.html
index 73a6fef64f..3e07774b79 100644
--- 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.html
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/elements/pipeline-elements-row.component.html
@@ -18,26 +18,21 @@
 
 <div fxFlex="100" fxLayout="column">
     <div fxLayout="row" fxFlex="100">
-        <div
-            fxFlex="{{ showDescription ? 30 : 100 }}}"
-            fxLayout="row"
-            style="margin-bottom: 10px"
-        >
-            <span class="draggable-icon {{ elementType }}">
-                <sp-pipeline-element
-                    [preview]="true"
-                    [pipelineElement]="_element"
-                ></sp-pipeline-element>
-            </span>
+        <div fxFlex="50px">
+            <div class="draggable-icon-editor tt" [ngClass]="elementType">
+                <span class="pe-container">
+                    <sp-pipeline-element
+                        style="margin-left: -3%"
+                        [iconStandSize]="true"
+                        [pipelineElement]="pipelineElement"
+                    ></sp-pipeline-element>
+                </span>
+            </div>
         </div>
-        <div
-            fxFlex="70"
-            fxLayout="column"
-            fxLayoutAlign="center left"
-            *ngIf="showDescription"
-        >
-            <b>{{ element.name }}</b>
-            {{ element.description }}
+        <div fxFlex fxLayoutAlign="start start" fxLayout="column">
+            <div class="element-name" fxLayoutAlign="start start">
+                {{ pipelineElement.name }}
+            </div>
         </div>
     </div>
 </div>
diff --git 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.ts
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/elements/pipeline-elements-row.component.ts
similarity index 69%
rename from 
ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.ts
rename to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/elements/pipeline-elements-row.component.ts
index 016a0c2114..1bee34607b 100644
--- 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements-row.component.ts
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/elements/pipeline-elements-row.component.ts
@@ -17,24 +17,21 @@
  */
 
 import { Component, Input, OnInit } from '@angular/core';
-import { PipelineElementUnion } from '../../../editor/model/editor.model';
-import { Pipeline } from '@streampipes/platform-services';
-import { PipelineElementTypeUtils } from '../../../editor/utils/editor.utils';
+import { PipelineElementUnion } from 
'../../../../../editor/model/editor.model';
+import { PipelineElementTypeUtils } from 
'../../../../../editor/utils/editor.utils';
 
 @Component({
     selector: 'sp-pipeline-elements-row',
     templateUrl: './pipeline-elements-row.component.html',
+    styleUrls: [
+        
'../../../../../editor/components/pipeline-element-icon-stand-row/pipeline-element-icon-stand-row.component.scss',
+    ],
 })
 export class PipelineElementsRowComponent implements OnInit {
     elementType: string;
 
     @Input()
-    pipeline: Pipeline;
-
-    @Input()
-    showDescription = true;
-
-    _element: PipelineElementUnion;
+    pipelineElement: PipelineElementUnion;
 
     constructor() {}
 
@@ -42,19 +39,9 @@ export class PipelineElementsRowComponent implements OnInit {
         this.updateType();
     }
 
-    get element() {
-        return this._element;
-    }
-
-    @Input()
-    set element(element: PipelineElementUnion) {
-        this._element = element;
-        this.updateType();
-    }
-
     updateType() {
         this.elementType = PipelineElementTypeUtils.toCssShortHand(
-            PipelineElementTypeUtils.fromType(this._element),
+            PipelineElementTypeUtils.fromType(this.pipelineElement),
         );
     }
 }
diff --git 
a/ui/src/app/editor/components/pipeline-element/pipeline-element.component.html 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.html
similarity index 63%
copy from 
ui/src/app/editor/components/pipeline-element/pipeline-element.component.html
copy to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.html
index 0ef40b4a24..284166d2dd 100644
--- 
a/ui/src/app/editor/components/pipeline-element/pipeline-element.component.html
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.html
@@ -16,10 +16,20 @@
   ~
   -->
 
-<img [src]="image" *ngIf="showImage" style="{{ iconSizeCss() }}" />
-<span
-    *ngIf="!showImage"
-    [ngClass]="iconStandSize ? 'text-small<' : 'element-text-icon'"
->
-    {{ iconText }}
-</span>
+<div fxLayout="row" fxFlex="100">
+    <div fxFlex>
+        <sp-pipeline-elements-row [pipelineElement]="pipelineElement">
+        </sp-pipeline-elements-row>
+    </div>
+    <div fxLayoutAlign="end center">
+        <button
+            (click)="openLogsDialog()"
+            mat-icon-button
+            color="accent"
+            matTooltip="Logs"
+            [disabled]="!pipelineRunning"
+        >
+            <mat-icon>topic</mat-icon>
+        </button>
+    </div>
+</div>
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.scss
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.scss
new file mode 100644
index 0000000000..e69de29bb2
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.ts
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.ts
new file mode 100644
index 0000000000..161caeee10
--- /dev/null
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component.ts
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ *
+ */
+
+import { Component, Input } from '@angular/core';
+import { PipelineElementUnion } from '../../../../editor/model/editor.model';
+import { SpLogEntry } from '@streampipes/platform-services';
+import { DialogService, PanelType } from '@streampipes/shared-ui';
+import { PipelineLogsDialogComponent } from 
'../../../dialogs/pipeline-logs/pipeline-logs-dialog.component';
+
+@Component({
+    selector: 'sp-pipeline-element-details-row',
+    templateUrl: './pipeline-element-details-row.component.html',
+    styleUrls: ['./pipeline-element-details-row.component.scss'],
+})
+export class PipelineElementDetailsRowComponent {
+    @Input()
+    pipelineElement: PipelineElementUnion;
+
+    @Input()
+    pipelineRunning: boolean;
+
+    @Input()
+    logInfo: SpLogEntry[] = [];
+
+    constructor(private dialogService: DialogService) {}
+
+    openLogsDialog(): void {
+        this.dialogService.open(PipelineLogsDialogComponent, {
+            panelType: PanelType.SLIDE_IN_PANEL,
+            width: '50vw',
+            title: 'Logs',
+            data: {
+                logInfo: this.logInfo || [],
+            },
+        });
+    }
+}
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.html
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.html
new file mode 100644
index 0000000000..b17081e3d7
--- /dev/null
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.html
@@ -0,0 +1,52 @@
+<!--
+  ~ 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="p-10" *ngIf="pipelineStatus.length > 0">
+    <div
+        fxFlex="100"
+        fxLayout="column"
+        fxLayoutGap="10px"
+        *ngFor="let status of pipelineStatus"
+    >
+        <div fxFlex="100" fxLayout="column" class="mb-10">
+            <div fxLayout="row">
+                <div fxFlex="50">
+                    <span class="status-time">{{
+                        status.timestamp | date: 'dd.MM.yyyy HH:mm'
+                    }}</span>
+                </div>
+                <div fxFlex="50">
+                    <span>{{ status.messageType }}</span>
+                </div>
+            </div>
+            <div>
+                <small
+                    ><i>{{ status.message }}</i></small
+                >
+            </div>
+        </div>
+    </div>
+</div>
+<div
+    fxLayout="column"
+    fxLayoutAlign="center center"
+    style="min-height: 100px; padding: 5px; padding-left: 15px"
+    *ngIf="pipelineStatus.length === 0"
+>
+    (no status information available)
+</div>
diff --git 
a/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.scss
 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.scss
similarity index 91%
rename from 
ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.scss
rename to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.scss
index 02ee1e39c1..03575c962d 100644
--- 
a/ui/src/app/pipeline-details/components/overview/pipeline-details-overview.component.scss
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * 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.
@@ -16,6 +16,7 @@
  *
  */
 
-.md-padding {
-    padding: 10px;
+.status-time {
+    font-weight: bold;
+    color: var(--color-primary);
 }
diff --git 
a/ui/src/app/pipeline-details/components/status/pipeline-status.component.ts 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.ts
similarity index 96%
rename from 
ui/src/app/pipeline-details/components/status/pipeline-status.component.ts
rename to 
ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.ts
index 8baecf1d1c..caa4a923d0 100644
--- a/ui/src/app/pipeline-details/components/status/pipeline-status.component.ts
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-expansion-panel/status/pipeline-status.component.ts
@@ -19,13 +19,14 @@
 import { Component, Input, OnInit } from '@angular/core';
 import {
     Pipeline,
-    PipelineStatusMessage,
     PipelineService,
+    PipelineStatusMessage,
 } from '@streampipes/platform-services';
 
 @Component({
     selector: 'sp-pipeline-status',
     templateUrl: './pipeline-status.component.html',
+    styleUrls: ['./pipeline-status.component.scss'],
 })
 export class PipelineStatusComponent implements OnInit {
     pipelineStatus: PipelineStatusMessage[];
diff --git 
a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.html
 
b/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.html
similarity index 57%
copy from 
ui/src/app/pipeline-details/components/preview/pipeline-preview.component.html
copy to 
ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.html
index 17253bebff..d740252a3f 100644
--- 
a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.html
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.html
@@ -16,19 +16,24 @@
   ~
   -->
 
-<sp-basic-inner-panel
-    [panelTitle]="'Preview: ' + pipeline.name"
-    innerPadding="0"
->
-    <div class="outer-assembly-preview">
-        <div class="canvas-preview-inner">
-            <div id="{{ jspcanvas }}" class="canvas-preview">
-                <sp-pipeline
-                    [canvasId]="jspcanvas"
-                    [rawPipelineModel]="rawPipelineModel"
-                    [preview]="true"
-                ></sp-pipeline>
-            </div>
-        </div>
+<div fxFlex="100" fxLayout="row" fxLayoutAlign="start center">
+    <div fxFlex></div>
+    <div fxLayoutAlign="end center">
+        <button
+            mat-button
+            color="accent"
+            class="mr-10"
+            matTooltip="Refresh"
+            (click)="reloadMetricsEmitter.emit()"
+        >
+            <i class="material-icons">refresh</i>
+            &nbsp;Refresh metrics
+        </button>
+        <mat-slide-toggle
+            [(ngModel)]="autoRefresh"
+            (ngModelChange)="autoRefreshChange.emit($event)"
+            color="accent"
+            >Auto refresh
+        </mat-slide-toggle>
     </div>
-</sp-basic-inner-panel>
+</div>
diff --git 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements.component.ts
 
b/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.ts
similarity index 66%
rename from 
ui/src/app/pipeline-details/components/elements/pipeline-elements.component.ts
rename to 
ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.ts
index e18cfdfb80..3ef8b9218c 100644
--- 
a/ui/src/app/pipeline-details/components/elements/pipeline-elements.component.ts
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.ts
@@ -16,20 +16,19 @@
  *
  */
 
-import { Component, Input } from '@angular/core';
-import { PipelineElementUnion } from '../../../editor/model/editor.model';
-import { Pipeline } from '@streampipes/platform-services';
+import { Component, EventEmitter, Input, Output } from '@angular/core';
 
 @Component({
-    selector: 'sp-pipeline-elements',
-    templateUrl: './pipeline-elements.component.html',
+    selector: 'sp-pipeline-details-toolbar',
+    templateUrl: './pipeline-details-toolbar.component.html',
 })
-export class PipelineElementsComponent {
+export class PipelineDetailsToolbarComponent {
     @Input()
-    pipeline: Pipeline;
+    autoRefresh: boolean;
 
-    @Input()
-    selectedElement: PipelineElementUnion;
+    @Output()
+    autoRefreshChange = new EventEmitter<boolean>();
 
-    constructor() {}
+    @Output()
+    reloadMetricsEmitter: EventEmitter<void> = new EventEmitter();
 }
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.html
 
b/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.html
deleted file mode 100644
index 76129ca8f2..0000000000
--- 
a/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.html
+++ /dev/null
@@ -1,85 +0,0 @@
-<!--
-  ~ 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.
-  ~
-  -->
-
-<sp-basic-nav-tabs
-    [spNavigationItems]="tabs"
-    [activeLink]="'logs'"
-    [showBackLink]="true"
-    [backLinkTarget]="['pipelines']"
->
-    <div nav fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
-        <button
-            mat-icon-button
-            color="accent"
-            class="mr-10"
-            matTooltip="Refresh"
-            (click)="triggerLogUpdate()"
-        >
-            <i class="material-icons">refresh</i>
-        </button>
-    </div>
-    <div fxLayout="column" class="page-container-padding" *ngIf="pipeline">
-        <div
-            fxFlex="100"
-            fxLayout="column"
-            class="page-container-padding-inner"
-        >
-            <sp-pipeline-preview
-                [jspcanvas]="'assembly-preview'"
-                [pipeline]="pipeline"
-                (selectedElementEmitter)="selectElement($event)"
-                style="margin-bottom: 15px"
-                class="md-padding"
-                *ngIf="pipelineAvailable"
-            ></sp-pipeline-preview>
-
-            <sp-basic-inner-panel panelTitle="Logs">
-                <div
-                    fxFlex="100"
-                    fxLayout="column"
-                    *ngIf="selectedElementId !== undefined"
-                >
-                    <div *ngIf="logInfos[selectedElementId]">
-                        <div
-                            *ngFor="let logEntry of 
logInfos[selectedElementId]"
-                        >
-                            <sp-exception-message
-                                [message]="logEntry.errorMessage"
-                                [messageTimestamp]="logEntry.timestamp"
-                                *ngIf="logEntry.errorMessage"
-                                class="mt-10"
-                            ></sp-exception-message>
-                        </div>
-                    </div>
-                    <div *ngIf="!logInfos[selectedElementId]">
-                        <h5 class="text-center">(no log messages 
available)</h5>
-                    </div>
-                </div>
-                <div
-                    fxFlex="100"
-                    fxLayout="column"
-                    *ngIf="selectedElementId === undefined"
-                >
-                    <h5 class="text-center">
-                        (click a pipeline element to view log messages)
-                    </h5>
-                </div>
-            </sp-basic-inner-panel>
-        </div>
-    </div>
-</sp-basic-nav-tabs>
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.scss
 
b/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.scss
deleted file mode 100644
index 13cbc4aacb..0000000000
--- 
a/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * 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.
- *
- */
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.ts
 
b/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.ts
deleted file mode 100644
index 5bc73f4468..0000000000
--- 
a/ui/src/app/pipeline-details/components/pipeline-logs/pipeline-logs.component.ts
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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.
- *
- */
-
-import { Component, OnInit } from '@angular/core';
-import { SpPipelineDetailsDirective } from '../sp-pipeline-details.directive';
-import { SpPipelineRoutes } from '../../../pipelines/pipelines.routes';
-import { ActivatedRoute } from '@angular/router';
-import {
-    PipelineMonitoringService,
-    PipelineService,
-    SpLogEntry,
-} from '@streampipes/platform-services';
-import { AuthService } from '../../../services/auth.service';
-import {
-    CurrentUserService,
-    SpBreadcrumbService,
-} from '@streampipes/shared-ui';
-import { PipelineElementUnion } from '../../../editor/model/editor.model';
-
-@Component({
-    selector: 'sp-pipeline-logs',
-    templateUrl: './pipeline-logs.component.html',
-    styleUrls: ['./pipeline-logs.component.scss'],
-})
-export class PipelineLogsComponent
-    extends SpPipelineDetailsDirective
-    implements OnInit
-{
-    logInfos: Record<string, SpLogEntry[]> = {};
-    selectedElementId: string;
-
-    constructor(
-        activatedRoute: ActivatedRoute,
-        pipelineService: PipelineService,
-        authService: AuthService,
-        currentUserService: CurrentUserService,
-        breadcrumbService: SpBreadcrumbService,
-        private pipelineMonitoringService: PipelineMonitoringService,
-    ) {
-        super(
-            activatedRoute,
-            pipelineService,
-            authService,
-            currentUserService,
-            breadcrumbService,
-        );
-    }
-
-    ngOnInit(): void {
-        super.onInit();
-    }
-
-    onPipelineAvailable(): void {
-        this.breadcrumbService.updateBreadcrumb([
-            SpPipelineRoutes.BASE,
-            { label: this.pipeline.name },
-            { label: 'Logs' },
-        ]);
-        this.receiveLogInfos();
-    }
-
-    receiveLogInfos(): void {
-        this.pipelineMonitoringService
-            .getLogInfoForPipeline(this.pipeline._id)
-            .subscribe(response => {
-                this.logInfos = response;
-            });
-    }
-
-    selectElement(pipelineElement: PipelineElementUnion): void {
-        this.selectedElementId = pipelineElement.elementId;
-    }
-
-    triggerLogUpdate(): void {
-        this.pipelineMonitoringService
-            .triggerMonitoringUpdate()
-            .subscribe(res => {
-                this.receiveLogInfos();
-            });
-    }
-}
diff --git 
a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.html
 
b/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.html
index 17253bebff..ca4a4fc397 100644
--- 
a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.html
+++ 
b/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.html
@@ -16,19 +16,16 @@
   ~
   -->
 
-<sp-basic-inner-panel
-    [panelTitle]="'Preview: ' + pipeline.name"
-    innerPadding="0"
->
-    <div class="outer-assembly-preview">
-        <div class="canvas-preview-inner">
-            <div id="{{ jspcanvas }}" class="canvas-preview">
-                <sp-pipeline
-                    [canvasId]="jspcanvas"
-                    [rawPipelineModel]="rawPipelineModel"
-                    [preview]="true"
-                ></sp-pipeline>
-            </div>
+<div class="outer-assembly-preview">
+    <div class="pipeline-canvas-outer canvas-preview-inner">
+        <div id="{{ jspcanvas }}" class="canvas-preview">
+            <sp-pipeline
+                [canvasId]="jspcanvas"
+                [metricsInfo]="metricsInfo"
+                [rawPipelineModel]="rawPipelineModel"
+                [preview]="true"
+            ></sp-pipeline>
         </div>
     </div>
-</sp-basic-inner-panel>
+    <ng-content></ng-content>
+</div>
diff --git 
a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts 
b/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts
index b0af149c57..ce0208628d 100644
--- 
a/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts
+++ 
b/ui/src/app/pipeline-details/components/preview/pipeline-preview.component.ts
@@ -16,15 +16,12 @@
  *
  */
 
+import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
 import {
-    Component,
-    EventEmitter,
-    Input,
-    OnDestroy,
-    OnInit,
-    Output,
-} from '@angular/core';
-import { Pipeline } from '@streampipes/platform-services';
+    Pipeline,
+    PipelineCanvasMetadata,
+    SpMetricsEntry,
+} from '@streampipes/platform-services';
 import {
     PipelineElementConfig,
     PipelineElementUnion,
@@ -43,11 +40,17 @@ export class PipelinePreviewComponent implements OnInit {
     @Input()
     jspcanvas: string;
 
+    @Input()
+    metricsInfo: Record<string, SpMetricsEntry>;
+
     rawPipelineModel: PipelineElementConfig[];
 
     @Input()
     pipeline: Pipeline;
 
+    @Input()
+    pipelineCanvasMetadata: PipelineCanvasMetadata;
+
     @Output()
     selectedElementEmitter: EventEmitter<PipelineElementUnion> =
         new EventEmitter<PipelineElementUnion>();
@@ -61,7 +64,7 @@ export class PipelinePreviewComponent implements OnInit {
 
     ngOnInit() {
         setTimeout(() => {
-            const elid = '#' + this.jspcanvas;
+            const canvasElementId = '#' + this.jspcanvas;
             this.rawPipelineModel = this.jsplumbService.makeRawPipeline(
                 this.pipeline,
                 true,
@@ -69,9 +72,10 @@ export class PipelinePreviewComponent implements OnInit {
             setTimeout(() => {
                 this.pipelinePositioningService.displayPipeline(
                     this.rawPipelineModel,
-                    elid,
-                    true,
+                    canvasElementId,
                     true,
+                    this.pipelineCanvasMetadata === undefined,
+                    this.pipelineCanvasMetadata,
                 );
                 const existingEndpointIds = [];
                 setTimeout(() => {
diff --git 
a/ui/src/app/pipeline-details/components/sp-pipeline-details.directive.ts 
b/ui/src/app/pipeline-details/components/sp-pipeline-details.directive.ts
deleted file mode 100644
index 5ced545ecc..0000000000
--- a/ui/src/app/pipeline-details/components/sp-pipeline-details.directive.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * 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.
- *
- */
-
-import { Directive } from '@angular/core';
-import { UserPrivilege } from '../../_enums/user-privilege.enum';
-import { ActivatedRoute } from '@angular/router';
-import { AuthService } from '../../services/auth.service';
-import { Pipeline, PipelineService } from '@streampipes/platform-services';
-import { SpPipelineDetailsTabs } from '../pipeline-details-tabs';
-import {
-    CurrentUserService,
-    SpBreadcrumbService,
-} from '@streampipes/shared-ui';
-
-@Directive()
-export abstract class SpPipelineDetailsDirective {
-    tabs = [];
-    hasPipelineWritePrivileges = false;
-    hasPipelineDeletePrivileges = false;
-
-    currentPipeline: string;
-    pipeline: Pipeline;
-    pipelineAvailable = false;
-
-    constructor(
-        protected activatedRoute: ActivatedRoute,
-        protected pipelineService: PipelineService,
-        protected authService: AuthService,
-        protected currentUserService: CurrentUserService,
-        protected breadcrumbService: SpBreadcrumbService,
-    ) {}
-
-    onInit(): void {
-        this.currentUserService.user$.subscribe(user => {
-            this.hasPipelineWritePrivileges = this.authService.hasRole(
-                UserPrivilege.PRIVILEGE_WRITE_PIPELINE,
-            );
-            this.hasPipelineDeletePrivileges = this.authService.hasRole(
-                UserPrivilege.PRIVILEGE_DELETE_PIPELINE,
-            );
-            const pipelineId = this.activatedRoute.snapshot.params.pipelineId;
-            if (pipelineId) {
-                this.tabs = new SpPipelineDetailsTabs().getTabs(pipelineId);
-                this.currentPipeline = pipelineId;
-                this.loadPipeline();
-            }
-        });
-    }
-
-    loadPipeline(): void {
-        this.pipelineService
-            .getPipelineById(this.currentPipeline)
-            .subscribe(pipeline => {
-                this.pipeline = pipeline;
-                this.pipelineAvailable = true;
-                this.onPipelineAvailable();
-            });
-    }
-
-    abstract onPipelineAvailable(): void;
-}
diff --git 
a/ui/src/app/pipeline-details/components/status/pipeline-status.component.html 
b/ui/src/app/pipeline-details/components/status/pipeline-status.component.html
deleted file mode 100644
index 6cc7ffecdf..0000000000
--- 
a/ui/src/app/pipeline-details/components/status/pipeline-status.component.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
-  ~ 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.
-  ~
-  -->
-
-<sp-basic-inner-panel panelTitle="Pipeline Status">
-    <div
-        fxLayout="column"
-        style="min-height: 100px; padding: 5px; padding-left: 15px"
-        *ngIf="pipelineStatus.length > 0"
-    >
-        <div fxLayout="row" fxFlex="100">
-            <div fxFlex="20">
-                <h5><b>Date</b></h5>
-            </div>
-            <div fxFlex="20">
-                <h5><b>Status</b></h5>
-            </div>
-            <div fxFlex="60">
-                <h5><b>Description</b></h5>
-            </div>
-            <div fxFlex="60">
-                <h5><b>Details</b></h5>
-            </div>
-        </div>
-        <div
-            fxFlex="100"
-            fxLayout="column"
-            *ngFor="let status of pipelineStatus"
-        >
-            <div fxFlex="100" fxLayout="row">
-                <div fxFlex="20">
-                    <h5>{{ status.timestamp | date: 'dd.MM.yyyy HH:mm' }}</h5>
-                </div>
-                <div fxFlex="20">
-                    <h5>{{ status.messageType }}</h5>
-                </div>
-                <div fxFlex="60">
-                    <h5>{{ status.message }}</h5>
-                </div>
-                <div fxFlex="60"><h5>-</h5></div>
-            </div>
-        </div>
-    </div>
-    <div
-        fxLayout="column"
-        fxLayoutAlign="center center"
-        style="min-height: 100px; padding: 5px; padding-left: 15px"
-        *ngIf="pipelineStatus.length === 0"
-    >
-        (no status information available)
-    </div>
-</sp-basic-inner-panel>
diff --git 
a/ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.html
 
b/ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.html
new file mode 100644
index 0000000000..a473730836
--- /dev/null
+++ 
b/ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.html
@@ -0,0 +1,48 @@
+<!--
+  ~ 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 class="sp-dialog-container">
+    <div class="sp-dialog-content">
+        <div fxFlex="100" fxLayout="column">
+            <div fxFlex="100" fxLayout="column">
+                <div *ngFor="let logEntry of logInfo">
+                    <sp-exception-message
+                        [message]="logEntry.errorMessage"
+                        [messageTimestamp]="logEntry.timestamp"
+                        *ngIf="logEntry.errorMessage"
+                        class="mt-10"
+                    ></sp-exception-message>
+                </div>
+                <div *ngIf="logInfo.length === 0">
+                    <h5 class="text-center">(no log messages available)</h5>
+                </div>
+            </div>
+        </div>
+    </div>
+    <mat-divider></mat-divider>
+    <div class="sp-dialog-actions">
+        <button
+            mat-button
+            mat-raised-button
+            class="mat-basic"
+            (click)="close()"
+        >
+            Close
+        </button>
+    </div>
+</div>
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.scss
 
b/ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.scss
similarity index 100%
rename from 
ui/src/app/pipeline-details/components/monitoring/widget/barchart/barchart-widget.component.scss
rename to 
ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.scss
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.scss
 
b/ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.ts
similarity index 59%
rename from 
ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.scss
rename to 
ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.ts
index 208fbef4e9..d81f72484b 100644
--- 
a/ui/src/app/pipeline-details/components/monitoring/pipeline-monitoring.component.scss
+++ 
b/ui/src/app/pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component.ts
@@ -16,33 +16,22 @@
  *
  */
 
-.add-options {
-    background-color: var(--color-bg-1);
-    border-bottom: 1px solid var(--color-bg-3);
-    padding-top: 10px;
-    padding-bottom: 10px;
-}
-
-.fixed-height {
-    width: 100%;
-    height: 50px;
-}
+import { Component, Input } from '@angular/core';
+import { SpLogEntry } from '@streampipes/platform-services';
+import { DialogRef } from '@streampipes/shared-ui';
 
-.page-container-padding-inner {
-    margin: 10px;
-}
+@Component({
+    selector: 'sp-pipeline-logs',
+    templateUrl: './pipeline-logs-dialog.component.html',
+    styleUrls: ['./pipeline-logs-dialog.component.scss'],
+})
+export class PipelineLogsDialogComponent {
+    @Input()
+    logInfo: SpLogEntry[] = [];
 
-.pipeline-element-statistics-panel {
-    padding: 10px;
-}
-
-.mb-10 {
-    margin-bottom: 10px;
-}
+    constructor(private dialogRef: DialogRef<PipelineLogsDialogComponent>) {}
 
-.error-message {
-    font-weight: bold;
-    margin-top: 15px;
-    margin-bottom: 15px;
-    font-size: 12pt;
+    close() {
+        this.dialogRef.close();
+    }
 }
diff --git a/ui/src/app/pipeline-details/pipeline-details-tabs.ts 
b/ui/src/app/pipeline-details/pipeline-details-tabs.ts
deleted file mode 100644
index 8cde55cbec..0000000000
--- a/ui/src/app/pipeline-details/pipeline-details-tabs.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.
- *
- */
-
-import { SpNavigationItem } from '@streampipes/shared-ui';
-
-export class SpPipelineDetailsTabs {
-    public getTabs(pipelineId: string): SpNavigationItem[] {
-        return [
-            {
-                itemId: 'overview',
-                itemTitle: 'Overview',
-                itemLink: ['pipelines', 'details', pipelineId, 'overview'],
-            },
-            {
-                itemId: 'monitoring',
-                itemTitle: 'Metrics',
-                itemLink: ['pipelines', 'details', pipelineId, 'metrics'],
-            },
-            {
-                itemId: 'logs',
-                itemTitle: 'Logs',
-                itemLink: ['pipelines', 'details', pipelineId, 'logs'],
-            },
-        ];
-    }
-}
diff --git a/ui/src/app/pipeline-details/pipeline-details.component.html 
b/ui/src/app/pipeline-details/pipeline-details.component.html
new file mode 100644
index 0000000000..f07f3464a6
--- /dev/null
+++ b/ui/src/app/pipeline-details/pipeline-details.component.html
@@ -0,0 +1,55 @@
+<!--
+  ~ 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.
+  ~
+  -->
+
+<sp-basic-view
+    [showBackLink]="true"
+    [backLinkTarget]="['pipelines']"
+    [padding]="false"
+>
+    <div nav fxFlex="100" fxLayoutAlign="start center" class="mr-5">
+        <sp-pipeline-details-toolbar
+            fxFlex="100"
+            [autoRefresh]="autoRefresh"
+            (autoRefreshChange)="autoRefresh = $event"
+            (reloadMetricsEmitter)="triggerReload()"
+        >
+        </sp-pipeline-details-toolbar>
+    </div>
+    <div fxFlex="100" fxLayout="column">
+        <sp-pipeline-preview
+            [jspcanvas]="'assembly-preview'"
+            [metricsInfo]="metricsInfo"
+            [pipeline]="pipeline"
+            [pipelineCanvasMetadata]="pipelineCanvasMetadata"
+            (selectedElementEmitter)="selectElement($event)"
+            style="display: flex; flex: 1 1"
+            *ngIf="pipelineAvailable"
+        >
+            <div class="expansion-panel" fxFlex="100" fxLayout="column">
+                <sp-pipeline-details-expansion-panel
+                    [hasWritePipelinePrivileges]="hasPipelineWritePrivileges"
+                    [hasDeletePipelinePrivileges]="hasPipelineDeletePrivileges"
+                    (reloadPipelineEmitter)="loadPipeline()"
+                    [logInfo]="logInfo"
+                    [pipeline]="pipeline"
+                >
+                </sp-pipeline-details-expansion-panel>
+            </div>
+        </sp-pipeline-preview>
+    </div>
+</sp-basic-view>
diff --git 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.scss
 b/ui/src/app/pipeline-details/pipeline-details.component.scss
similarity index 84%
rename from 
ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.scss
rename to ui/src/app/pipeline-details/pipeline-details.component.scss
index f399ceb4ca..56daac3ff5 100644
--- 
a/ui/src/app/pipeline-details/components/monitoring/statistics/pipeline-element-statistics.component.scss
+++ b/ui/src/app/pipeline-details/pipeline-details.component.scss
@@ -1,4 +1,4 @@
-/*
+/*!
  * 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.
@@ -16,10 +16,14 @@
  *
  */
 
-.mb-10 {
-    margin-bottom: 10px;
+.md-padding {
+    padding: 10px;
 }
 
-.mt--10 {
-    margin-top: -10px;
+.expansion-panel {
+    position: absolute;
+    right: 10px;
+    top: 10px;
+    width: 300px;
+    height: 97%;
 }
diff --git a/ui/src/app/pipeline-details/pipeline-details.component.ts 
b/ui/src/app/pipeline-details/pipeline-details.component.ts
new file mode 100644
index 0000000000..b56bf65f70
--- /dev/null
+++ b/ui/src/app/pipeline-details/pipeline-details.component.ts
@@ -0,0 +1,166 @@
+/*
+ * 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.
+ *
+ */
+
+import { Component, OnDestroy, OnInit } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
+import { AuthService } from '../services/auth.service';
+import {
+    Pipeline,
+    PipelineCanvasMetadata,
+    PipelineCanvasMetadataService,
+    PipelineMonitoringService,
+    PipelineService,
+    SpLogEntry,
+    SpMetricsEntry,
+} from '@streampipes/platform-services';
+import { PipelineElementUnion } from '../editor/model/editor.model';
+import {
+    CurrentUserService,
+    SpBreadcrumbService,
+} from '@streampipes/shared-ui';
+import { SpPipelineRoutes } from '../pipelines/pipelines.routes';
+import { UserPrivilege } from '../_enums/user-privilege.enum';
+import { forkJoin, interval, Observable, Subscription } from 'rxjs';
+import { filter, switchMap } from 'rxjs/operators';
+
+@Component({
+    selector: 'sp-pipeline-details-overview-component',
+    templateUrl: './pipeline-details.component.html',
+    styleUrls: ['./pipeline-details.component.scss'],
+})
+export class SpPipelineDetailsComponent implements OnInit, OnDestroy {
+    hasPipelineWritePrivileges = false;
+    hasPipelineDeletePrivileges = false;
+
+    currentPipelineId: string;
+
+    pipeline: Pipeline;
+    pipelineCanvasMetadata: PipelineCanvasMetadata;
+
+    pipelineAvailable = false;
+    selectedElement: PipelineElementUnion;
+    autoRefresh = false;
+    metricsInfo: Record<string, SpMetricsEntry> = {};
+    logInfo: Record<string, SpLogEntry[]> = {};
+
+    currentUserSub: Subscription;
+    autoRefreshSub: Subscription;
+
+    constructor(
+        private activatedRoute: ActivatedRoute,
+        private pipelineService: PipelineService,
+        private pipelineCanvasService: PipelineCanvasMetadataService,
+        private authService: AuthService,
+        private currentUserService: CurrentUserService,
+        private breadcrumbService: SpBreadcrumbService,
+        private pipelineMonitoringService: PipelineMonitoringService,
+    ) {}
+
+    ngOnInit(): void {
+        this.currentUserSub = this.currentUserService.user$.subscribe(user => {
+            this.hasPipelineWritePrivileges = this.authService.hasRole(
+                UserPrivilege.PRIVILEGE_WRITE_PIPELINE,
+            );
+            this.hasPipelineDeletePrivileges = this.authService.hasRole(
+                UserPrivilege.PRIVILEGE_DELETE_PIPELINE,
+            );
+            const pipelineId = this.activatedRoute.snapshot.params.pipelineId;
+            if (pipelineId) {
+                this.currentPipelineId = pipelineId;
+                this.loadPipeline();
+            }
+        });
+    }
+
+    loadPipeline(): void {
+        forkJoin([
+            this.pipelineService.getPipelineById(this.currentPipelineId),
+            this.pipelineCanvasService.getPipelineCanvasMetadata(
+                this.currentPipelineId,
+            ),
+        ]).subscribe(res => {
+            this.pipeline = res[0];
+            this.pipelineCanvasMetadata = res[1];
+            this.pipelineAvailable = true;
+            this.onPipelineAvailable();
+        });
+    }
+
+    selectElement(element: PipelineElementUnion) {
+        this.selectedElement = element;
+    }
+
+    onPipelineAvailable(): void {
+        this.triggerReload();
+        this.setupAutoRefresh();
+        this.breadcrumbService.updateBreadcrumb([
+            SpPipelineRoutes.BASE,
+            { label: this.pipeline.name },
+            { label: 'Overview' },
+        ]);
+    }
+
+    setupAutoRefresh(): void {
+        this.autoRefreshSub = interval(5000)
+            .pipe(
+                filter(() => this.autoRefresh),
+                switchMap(() => this.getMonitoringObservables()),
+            )
+            .subscribe(res => this.onMonitoringResultAvailable(res));
+    }
+
+    getMonitoringObservables(): Observable<any> {
+        return forkJoin([
+            this.getMetricsObservable(),
+            this.getLogsObservable(),
+        ]);
+    }
+
+    triggerReload(): void {
+        forkJoin([
+            this.getMetricsObservable(),
+            this.getLogsObservable(),
+        ]).subscribe(res => {
+            this.onMonitoringResultAvailable(res);
+        });
+    }
+
+    onMonitoringResultAvailable(
+        res: [Record<string, SpMetricsEntry>, Record<string, SpLogEntry[]>],
+    ): void {
+        this.metricsInfo = res[0];
+        this.logInfo = res[1];
+    }
+
+    getMetricsObservable(): Observable<Record<string, SpMetricsEntry>> {
+        return this.pipelineMonitoringService.getMetricsInfoForPipeline(
+            this.currentPipelineId,
+        );
+    }
+
+    getLogsObservable(): Observable<Record<string, SpLogEntry[]>> {
+        return this.pipelineMonitoringService.getLogInfoForPipeline(
+            this.currentPipelineId,
+        );
+    }
+
+    ngOnDestroy() {
+        this.currentUserSub?.unsubscribe();
+        this.autoRefreshSub?.unsubscribe();
+    }
+}
diff --git a/ui/src/app/pipeline-details/pipeline-details.module.ts 
b/ui/src/app/pipeline-details/pipeline-details.module.ts
index 5fde41afec..8b15a1fca6 100644
--- a/ui/src/app/pipeline-details/pipeline-details.module.ts
+++ b/ui/src/app/pipeline-details/pipeline-details.module.ts
@@ -25,20 +25,22 @@ import { CommonModule } from '@angular/common';
 import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
 import { PipelinePreviewComponent } from 
'./components/preview/pipeline-preview.component';
 import { EditorModule } from '../editor/editor.module';
-import { PipelineActionsComponent } from 
'./components/actions/pipeline-actions.component';
-import { PipelineStatusComponent } from 
'./components/status/pipeline-status.component';
-import { PipelineElementsComponent } from 
'./components/elements/pipeline-elements.component';
-import { PipelineElementsRowComponent } from 
'./components/elements/pipeline-elements-row.component';
+import { PipelineActionsComponent } from 
'./components/pipeline-details-expansion-panel/actions/pipeline-actions.component';
+import { PipelineStatusComponent } from 
'./components/pipeline-details-expansion-panel/status/pipeline-status.component';
+import { PipelineElementsRowComponent } from 
'./components/pipeline-details-expansion-panel/pipeline-element-details-row/elements/pipeline-elements-row.component';
 import { CoreUiModule } from '../core-ui/core-ui.module';
-import { PipelineMonitoringComponent } from 
'./components/monitoring/pipeline-monitoring.component';
-import { PipelineElementStatisticsComponent } from 
'./components/monitoring/statistics/pipeline-element-statistics.component';
-import { NgxChartsModule } from '@swimlane/ngx-charts';
-import { BarchartWidgetComponent } from 
'./components/monitoring/widget/barchart/barchart-widget.component';
 import { PlatformServicesModule } from '@streampipes/platform-services';
-import { SpPipelineDetailsOverviewComponent } from 
'./components/overview/pipeline-details-overview.component';
+import { SpPipelineDetailsComponent } from './pipeline-details.component';
 import { SharedUiModule } from '@streampipes/shared-ui';
-import { PipelineLogsComponent } from 
'./components/pipeline-logs/pipeline-logs.component';
+import { PipelineLogsDialogComponent } from 
'./dialogs/pipeline-logs/pipeline-logs-dialog.component';
 import { MatIconModule } from '@angular/material/icon';
+import { PipelineDetailsExpansionPanelComponent } from 
'./components/pipeline-details-expansion-panel/pipeline-details-expansion-panel.component';
+import { MatExpansionModule } from '@angular/material/expansion';
+import { PipelineElementDetailsRowComponent } from 
'./components/pipeline-details-expansion-panel/pipeline-element-details-row/pipeline-element-details-row.component';
+import { MatTooltipModule } from '@angular/material/tooltip';
+import { PipelineDetailsToolbarComponent } from 
'./components/pipeline-details-toolbar/pipeline-details-toolbar.component';
+import { MatSlideToggleModule } from '@angular/material/slide-toggle';
+import { MatDivider } from '@angular/material/divider';
 
 @NgModule({
     imports: [
@@ -50,24 +52,26 @@ import { MatIconModule } from '@angular/material/icon';
         MatIconModule,
         CommonModule,
         MatProgressSpinnerModule,
-        NgxChartsModule,
+        MatTooltipModule,
         EditorModule,
         FormsModule,
         ReactiveFormsModule,
         PlatformServicesModule,
         SharedUiModule,
+        MatExpansionModule,
+        MatSlideToggleModule,
+        MatDivider,
     ],
     declarations: [
         PipelineActionsComponent,
-        PipelineElementsComponent,
         PipelineElementsRowComponent,
-        PipelineElementStatisticsComponent,
-        PipelineLogsComponent,
-        PipelineMonitoringComponent,
+        PipelineLogsDialogComponent,
         PipelineStatusComponent,
         PipelinePreviewComponent,
-        BarchartWidgetComponent,
-        SpPipelineDetailsOverviewComponent,
+        SpPipelineDetailsComponent,
+        PipelineDetailsExpansionPanelComponent,
+        PipelineElementDetailsRowComponent,
+        PipelineDetailsToolbarComponent,
     ],
     providers: [],
     exports: [],
diff --git a/ui/src/app/pipelines/pipelines.module.ts 
b/ui/src/app/pipelines/pipelines.module.ts
index 74f209e7e8..ced6732122 100644
--- a/ui/src/app/pipelines/pipelines.module.ts
+++ b/ui/src/app/pipelines/pipelines.module.ts
@@ -38,9 +38,8 @@ import { EditorModule } from '../editor/editor.module';
 import { PipelineDetailsModule } from 
'../pipeline-details/pipeline-details.module';
 import { RouterModule } from '@angular/router';
 import { EditorComponent } from '../editor/editor.component';
-import { SpPipelineDetailsOverviewComponent } from 
'../pipeline-details/components/overview/pipeline-details-overview.component';
-import { PipelineMonitoringComponent } from 
'../pipeline-details/components/monitoring/pipeline-monitoring.component';
-import { PipelineLogsComponent } from 
'../pipeline-details/components/pipeline-logs/pipeline-logs.component';
+import { SpPipelineDetailsComponent } from 
'../pipeline-details/pipeline-details.component';
+import { PipelineLogsDialogComponent } from 
'../pipeline-details/dialogs/pipeline-logs/pipeline-logs-dialog.component';
 import { FunctionsOverviewComponent } from 
'./components/functions-overview/functions-overview.component';
 import { SpFunctionsMetricsComponent } from 
'./components/functions-overview/functions-metrics/functions-metrics.component';
 import { SpFunctionsLogsComponent } from 
'./components/functions-overview/functions-logs/functions-logs.component';
@@ -94,15 +93,11 @@ import { MatIconModule } from '@angular/material/icon';
                             },
                             {
                                 path: 'overview',
-                                component: SpPipelineDetailsOverviewComponent,
-                            },
-                            {
-                                path: 'metrics',
-                                component: PipelineMonitoringComponent,
+                                component: SpPipelineDetailsComponent,
                             },
                             {
                                 path: 'logs',
-                                component: PipelineLogsComponent,
+                                component: PipelineLogsDialogComponent,
                             },
                         ],
                     },
diff --git a/ui/src/scss/sp/main.scss b/ui/src/scss/sp/main.scss
index 269701f473..338900a90a 100644
--- a/ui/src/scss/sp/main.scss
+++ b/ui/src/scss/sp/main.scss
@@ -621,9 +621,9 @@ md-content {
         0 1px 3px 0 rgba(0, 0, 0, 0.2),
         0 1px 1px 0 rgba(0, 0, 0, 0.14),
         0 2px 1px -1px rgba(0, 0, 0, 0.12);
-    padding: 5px;
     border: 1px solid var(--color-bg-2);
-    height: 300px;
+    display: flex;
+    flex: 1 1 0;
     max-width: 100%;
 
     background-color: var(--color-bg-1);

Reply via email to