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

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


The following commit(s) were added to refs/heads/dev by this push:
     new e55e4fdf04 Add topics information to pipeline editor in view mode 
(#3326)
e55e4fdf04 is described below

commit e55e4fdf04ee5352cda2b7700b6bf8bd8e48efbf
Author: Marcel Früholz <[email protected]>
AuthorDate: Wed Nov 13 15:37:08 2024 +0100

    Add topics information to pipeline editor in view mode (#3326)
---
 .../adapter-code-panel.component.html              |   1 +
 .../configuration-code-panel.component.html        |  28 ++-
 .../configuration-code-panel.component.scss        |  14 ++
 .../configuration-code-panel.component.ts          |  23 ++-
 ui/src/app/core-ui/core-ui.module.ts               |   5 +
 ui/src/app/core-ui/pipes/yaml-pretty-print.pipe.ts |   2 +-
 ui/src/app/core-ui/topics/topics.component.html    | 213 +++++++++++++++++++++
 .../topics.component.scss}                         |  23 ++-
 ui/src/app/core-ui/topics/topics.component.ts      |  77 ++++++++
 .../components/pipeline/pipeline.component.html    |  12 ++
 .../components/pipeline/pipeline.component.scss}   |  35 ++--
 .../components/pipeline/pipeline.component.ts      |   8 +
 .../save-pipeline-settings.component.html          |   1 +
 ui/src/app/editor/services/editor.service.ts       |  12 ++
 .../pipeline-code-dialog.component.html            |   1 +
 .../pipeline-details/pipeline-details.module.ts    |   2 +
 16 files changed, 431 insertions(+), 26 deletions(-)

diff --git 
a/ui/src/app/connect/components/adapter-code-panel/adapter-code-panel.component.html
 
b/ui/src/app/connect/components/adapter-code-panel/adapter-code-panel.component.html
index 8a05afabd3..6f553c63e3 100644
--- 
a/ui/src/app/connect/components/adapter-code-panel/adapter-code-panel.component.html
+++ 
b/ui/src/app/connect/components/adapter-code-panel/adapter-code-panel.component.html
@@ -18,6 +18,7 @@
 
 <div fxFlex="100" *ngIf="compactAdapter" class="mt-10">
     <sp-configuration-code-panel
+        *ngIf="compactAdapter"
         [configuration]="compactAdapter"
         [maxHeight]="maxHeight"
     >
diff --git 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html
 
b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html
index a6590ce049..7e232c3089 100644
--- 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html
+++ 
b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.html
@@ -16,8 +16,23 @@
   ~
   -->
 
-<mat-tab-group color="accent" [mat-stretch-tabs]="false">
+<mat-tab-group
+    color="accent"
+    [mat-stretch-tabs]="false"
+    (selectedTabChange)="onTabChanged($event)"
+>
     <mat-tab label="YAML">
+        <div class="container-copy-button-container">
+            <div class="copy-button-container">
+                <button
+                    mat-icon-button
+                    [cdkCopyToClipboard]="currentConfiguration"
+                    matTooltip="Copy"
+                >
+                    <mat-icon>content_copy</mat-icon>
+                </button>
+            </div>
+        </div>
         <pre
             [innerHTML]="configuration | yamlpretty"
             class="preview-text"
@@ -26,6 +41,17 @@
         ></pre>
     </mat-tab>
     <mat-tab label="JSON">
+        <div class="container-copy-button-container">
+            <div class="copy-button-container">
+                <button
+                    mat-icon-button
+                    [cdkCopyToClipboard]="currentConfiguration"
+                    matTooltip="Copy"
+                >
+                    <mat-icon>content_copy</mat-icon>
+                </button>
+            </div>
+        </div>
         <pre
             [innerHTML]="configuration | jsonpretty"
             class="preview-text"
diff --git 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
 
b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
index c02ba8acc6..4025845c82 100644
--- 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
+++ 
b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
@@ -28,3 +28,17 @@
     overflow-y: scroll;
     white-space: pre-wrap;
 }
+
+.mat-mdc-icon-button {
+    color: #fff;
+}
+
+.copy-button-container {
+    position: absolute;
+    right: 20px;
+    top: 20px;
+}
+
+.container-copy-button-container {
+    position: relative;
+}
diff --git 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.ts
 
b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.ts
index bf8deb6418..9c3a88a970 100644
--- 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.ts
+++ 
b/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.ts
@@ -17,16 +17,37 @@
  */
 
 import { Component, Input, OnInit } from '@angular/core';
+import { stringify } from 'yaml';
+import { MatTabChangeEvent } from '@angular/material/tabs';
 
 @Component({
     selector: 'sp-configuration-code-panel',
     templateUrl: './configuration-code-panel.component.html',
     styleUrls: ['./configuration-code-panel.component.scss'],
 })
-export class ConfigurationCodePanelComponent {
+export class ConfigurationCodePanelComponent implements OnInit {
     @Input()
     configuration: any;
 
     @Input()
     maxHeight = '300px';
+
+    configurationYaml: string;
+    configurationJson: string;
+
+    currentConfiguration: string;
+
+    ngOnInit() {
+        this.configurationYaml = stringify(this.configuration);
+        this.configurationJson = JSON.stringify(this.configuration);
+        this.currentConfiguration = this.configurationYaml;
+    }
+
+    onTabChanged(event: MatTabChangeEvent) {
+        if (event.index === 0) {
+            this.currentConfiguration = this.configurationYaml;
+        } else {
+            this.currentConfiguration = this.configurationJson;
+        }
+    }
 }
diff --git a/ui/src/app/core-ui/core-ui.module.ts 
b/ui/src/app/core-ui/core-ui.module.ts
index 5a8815dce0..bd0c996d6e 100644
--- a/ui/src/app/core-ui/core-ui.module.ts
+++ b/ui/src/app/core-ui/core-ui.module.ts
@@ -26,6 +26,7 @@ import { MatNativeDateModule } from '@angular/material/core';
 import { MatDatepickerModule } from '@angular/material/datepicker';
 import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
 import { MatSnackBarModule } from '@angular/material/snack-bar';
+import { ClipboardModule } from '@angular/cdk/clipboard';
 
 import { MatChipsModule } from '@angular/material/chips';
 import { MatSliderModule } from '@angular/material/slider';
@@ -119,6 +120,7 @@ import { PipelineElementTemplateConfigItemComponent } from 
'./pipeline-element-t
 import { ConfigurationCodePanelComponent } from 
'./configuration-code-panel/configuration-code-panel.component';
 import { JsonPrettyPrintPipe } from './pipes/json-pretty-print.pipe';
 import { YamlPrettyPrintPipe } from './pipes/yaml-pretty-print.pipe';
+import { TopicsComponent } from './topics/topics.component';
 
 @NgModule({
     imports: [
@@ -151,6 +153,7 @@ import { YamlPrettyPrintPipe } from 
'./pipes/yaml-pretty-print.pipe';
         ReactiveFormsModule,
         FormsModule,
         CdkTableModule,
+        ClipboardModule,
         MatAutocompleteModule,
         MatSnackBarModule,
         MatProgressSpinnerModule,
@@ -182,6 +185,7 @@ import { YamlPrettyPrintPipe } from 
'./pipes/yaml-pretty-print.pipe';
         PipelineElementRuntimeInfoComponent,
         PipelineElementDocumentationComponent,
         HelpComponent,
+        TopicsComponent,
         StaticAnyInputComponent,
         StaticPropertyComponent,
         StaticFreeInputComponent,
@@ -236,6 +240,7 @@ import { YamlPrettyPrintPipe } from 
'./pipes/yaml-pretty-print.pipe';
         PipelineElementRuntimeInfoComponent,
         PipelineElementDocumentationComponent,
         HelpComponent,
+        TopicsComponent,
         StaticAnyInputComponent,
         StaticPropertyComponent,
         StaticFreeInputComponent,
diff --git a/ui/src/app/core-ui/pipes/yaml-pretty-print.pipe.ts 
b/ui/src/app/core-ui/pipes/yaml-pretty-print.pipe.ts
index 88f8b4b459..233bb6f11d 100644
--- a/ui/src/app/core-ui/pipes/yaml-pretty-print.pipe.ts
+++ b/ui/src/app/core-ui/pipes/yaml-pretty-print.pipe.ts
@@ -17,7 +17,7 @@
  */
 
 import { Injectable, Pipe, PipeTransform } from '@angular/core';
-import { parse, stringify } from 'yaml';
+import { stringify } from 'yaml';
 
 @Pipe({
     name: 'yamlpretty',
diff --git a/ui/src/app/core-ui/topics/topics.component.html 
b/ui/src/app/core-ui/topics/topics.component.html
new file mode 100644
index 0000000000..73c5be895c
--- /dev/null
+++ b/ui/src/app/core-ui/topics/topics.component.html
@@ -0,0 +1,213 @@
+<!--
+  ~ 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 p-15" fxLayout="column">
+        <div fxLayout="row" fxFlex="100">
+            <div fxLayout="column" fxFlex>
+                <h4>{{ pipelineElement?.name }}</h4>
+                <small>{{ pipelineElement?.description }}</small>
+            </div>
+            <div class="element-id" fxLayoutAlign="end start">
+                <span>ID</span>&nbsp;
+                <b>{{
+                    isDataStream
+                        ? pipelineElement?.elementId
+                        : pipelineElement?.appId
+                }}</b>
+            </div>
+        </div>
+
+        <mat-tab-group
+            color="accent"
+            [selectedIndex]="selectedTabIndex"
+            (selectedIndexChange)="selectedTabIndex = $event"
+        >
+            <mat-tab *ngFor="let tab of tabs" [label]="tab"></mat-tab>
+        </mat-tab-group>
+
+        <div *ngIf="selectedTabIndex === 0">
+            <ng-container *ngIf="isSpDataStream()">
+                <table
+                    mat-table
+                    [dataSource]="
+                        pipelineElement?.eventGrounding?.transportProtocols
+                    "
+                >
+                    <ng-container matColumnDef="outputTopics">
+                        <th mat-header-cell *matHeaderCellDef>
+                            <strong>Output Topics</strong>
+                        </th>
+                        <td mat-cell *matCellDef="let element">
+                            <div
+                                fxLayout="row"
+                                fxLayoutAlign="space-between center"
+                            >
+                                <span>{{
+                                    element?.topicDefinition?.actualTopicName
+                                }}</span>
+                                <button
+                                    mat-icon-button
+                                    [cdkCopyToClipboard]="
+                                        element.topicDefinition.actualTopicName
+                                    "
+                                    matTooltip="Copy"
+                                >
+                                    <mat-icon>content_copy</mat-icon>
+                                </button>
+                            </div>
+                        </td>
+                    </ng-container>
+                    <tr mat-header-row 
*matHeaderRowDef="['outputTopics']"></tr>
+                    <tr
+                        mat-row
+                        *matRowDef="let row; columns: ['outputTopics']"
+                    ></tr>
+                </table>
+            </ng-container>
+
+            <ng-container *ngIf="isDataProcessorInvocation()">
+                <table mat-table [dataSource]="pipelineElement?.inputStreams">
+                    <ng-container matColumnDef="inputTopics">
+                        <th mat-header-cell *matHeaderCellDef>
+                            <strong>Input Topics</strong>
+                        </th>
+                        <td mat-cell *matCellDef="let element">
+                            <div
+                                fxLayout="row"
+                                fxLayoutAlign="space-between center"
+                            >
+                                <span>{{
+                                    element?.eventGrounding
+                                        ?.transportProtocols?.[0]
+                                        ?.topicDefinition?.actualTopicName
+                                }}</span>
+                                <button
+                                    mat-icon-button
+                                    [cdkCopyToClipboard]="
+                                        element?.eventGrounding
+                                            ?.transportProtocols?.[0]
+                                            ?.topicDefinition?.actualTopicName
+                                    "
+                                    matTooltip="Copy"
+                                >
+                                    <mat-icon>content_copy</mat-icon>
+                                </button>
+                            </div>
+                        </td>
+                    </ng-container>
+                    <tr mat-header-row *matHeaderRowDef="['inputTopics']"></tr>
+                    <tr
+                        mat-row
+                        *matRowDef="let row; columns: ['inputTopics']"
+                    ></tr>
+                </table>
+
+                <table
+                    mat-table
+                    [dataSource]="
+                        pipelineElement?.outputStream?.eventGrounding
+                            ?.transportProtocols
+                    "
+                >
+                    <ng-container matColumnDef="outputTopics">
+                        <th mat-header-cell *matHeaderCellDef>
+                            <strong>Output Topics</strong>
+                        </th>
+                        <td mat-cell *matCellDef="let element">
+                            <div
+                                fxLayout="row"
+                                fxLayoutAlign="space-between center"
+                            >
+                                <span>{{
+                                    element?.topicDefinition?.actualTopicName
+                                }}</span>
+                                <button
+                                    mat-icon-button
+                                    [cdkCopyToClipboard]="
+                                        element?.topicDefinition
+                                            ?.actualTopicName
+                                    "
+                                    matTooltip="Copy"
+                                >
+                                    <mat-icon>content_copy</mat-icon>
+                                </button>
+                            </div>
+                        </td>
+                    </ng-container>
+                    <tr mat-header-row 
*matHeaderRowDef="['outputTopics']"></tr>
+                    <tr
+                        mat-row
+                        *matRowDef="let row; columns: ['outputTopics']"
+                    ></tr>
+                </table>
+            </ng-container>
+
+            <ng-container *ngIf="isDataSinkInvocation()">
+                <table mat-table [dataSource]="pipelineElement?.inputStreams">
+                    <ng-container matColumnDef="inputTopics">
+                        <th mat-header-cell *matHeaderCellDef>
+                            <strong>Input Topics</strong>
+                        </th>
+                        <td mat-cell *matCellDef="let element">
+                            <div
+                                fxLayout="row"
+                                fxLayoutAlign="space-between center"
+                            >
+                                <span>{{
+                                    element?.eventGrounding
+                                        ?.transportProtocols?.[0]
+                                        ?.topicDefinition?.actualTopicName
+                                }}</span>
+                                <button
+                                    mat-icon-button
+                                    [cdkCopyToClipboard]="
+                                        element?.eventGrounding
+                                            ?.transportProtocols?.[0]
+                                            ?.topicDefinition?.actualTopicName
+                                    "
+                                    matTooltip="Copy"
+                                >
+                                    <mat-icon>content_copy</mat-icon>
+                                </button>
+                            </div>
+                        </td>
+                    </ng-container>
+                    <tr mat-header-row *matHeaderRowDef="['inputTopics']"></tr>
+                    <tr
+                        mat-row
+                        *matRowDef="let row; columns: ['inputTopics']"
+                    ></tr>
+                </table>
+            </ng-container>
+        </div>
+    </div>
+
+    <mat-divider></mat-divider>
+
+    <div class="sp-dialog-actions actions-align-right">
+        <button
+            mat-button
+            mat-raised-button
+            class="mat-basic"
+            (click)="close()"
+        >
+            Close
+        </button>
+    </div>
+</div>
diff --git 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
 b/ui/src/app/core-ui/topics/topics.component.scss
similarity index 76%
copy from 
ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
copy to ui/src/app/core-ui/topics/topics.component.scss
index c02ba8acc6..c077f68f35 100644
--- 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
+++ b/ui/src/app/core-ui/topics/topics.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,15 +16,14 @@
  *
  */
 
-.preview-text {
-    background-color: black;
-    font:
-        9pt Inconsolata,
-        monospace;
-    text-shadow: 0 0 5px #c8c8c8;
-    color: white;
-    padding: 10px;
-    max-width: 100%;
-    overflow-y: scroll;
-    white-space: pre-wrap;
+@import '../../../scss/sp/sp-dialog.scss';
+
+.element-id {
+    border-radius: 5px;
+    margin-right: 10px;
+    margin-top: 5px;
+    margin-bottom: 5px;
+    font-size: small;
+    display: inline-block;
+    padding: 5px;
 }
diff --git a/ui/src/app/core-ui/topics/topics.component.ts 
b/ui/src/app/core-ui/topics/topics.component.ts
new file mode 100644
index 0000000000..2ce28d6dc7
--- /dev/null
+++ b/ui/src/app/core-ui/topics/topics.component.ts
@@ -0,0 +1,77 @@
+/*
+ * 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,
+} from '@streampipes/platform-services';
+import { DialogRef } from '@streampipes/shared-ui';
+import { PipelineElementUnion } from '../../editor/model/editor.model';
+
+@Component({
+    selector: 'sp-pipeline-element-topics',
+    templateUrl: './topics.component.html',
+    styleUrls: ['./topics.component.scss'],
+})
+export class TopicsComponent implements OnInit {
+    selectedTabIndex = 0;
+
+    availableTabs = ['Topics', 'Code'];
+    tabs: string[] = [];
+
+    @Input()
+    pipelineElement: PipelineElementUnion;
+    isDataStream: boolean;
+
+    constructor(private dialogRef: DialogRef<TopicsComponent>) {}
+
+    ngOnInit() {
+        if (
+            this.pipelineElement instanceof SpDataStream ||
+            this.pipelineElement instanceof DataProcessorInvocation ||
+            this.pipelineElement instanceof DataSinkInvocation
+        ) {
+            this.tabs = this.availableTabs;
+        } else {
+            this.tabs = [this.availableTabs[1]];
+            this.selectedTabIndex = 1;
+        }
+    }
+
+    isSpDataStream(): boolean {
+        return this.pipelineElement instanceof SpDataStream;
+    }
+
+    isDataProcessorInvocation(): boolean {
+        return this.pipelineElement instanceof DataProcessorInvocation;
+    }
+
+    isDataSinkInvocation(): boolean {
+        return this.pipelineElement instanceof DataSinkInvocation;
+    }
+
+    close() {
+        setTimeout(() => {
+            this.dialogRef.close();
+        });
+    }
+
+    protected readonly SpDataStream = SpDataStream;
+}
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.html 
b/ui/src/app/editor/components/pipeline/pipeline.component.html
index 20b984a570..8b77b5b017 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.html
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.html
@@ -26,6 +26,7 @@
     *ngFor="
         let pipelineElementConfig of rawPipelineModel | enabledPipelineElement
     "
+    style="position: relative"
 >
     <sp-dropped-pipeline-element
         [allElements]="allElements"
@@ -41,4 +42,15 @@
         (deleteEmitter)="handleDeleteOption($event)"
     >
     </sp-dropped-pipeline-element>
+    <div class="topics-button customize-button" *ngIf="readonly">
+        <button
+            class="topics-icon-button"
+            mat-icon-button
+            matTooltip="View Topics"
+            [matTooltipPosition]="'above'"
+            (click)="openTopicsDialog(pipelineElementConfig)"
+        >
+            <i class="material-icons topics-icon-size">code</i>
+        </button>
+    </div>
 </div>
diff --git 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
 b/ui/src/app/editor/components/pipeline/pipeline.component.scss
similarity index 65%
copy from 
ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
copy to ui/src/app/editor/components/pipeline/pipeline.component.scss
index c02ba8acc6..4d3c139be2 100644
--- 
a/ui/src/app/core-ui/configuration-code-panel/configuration-code-panel.component.scss
+++ b/ui/src/app/editor/components/pipeline/pipeline.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,15 +16,28 @@
  *
  */
 
-.preview-text {
-    background-color: black;
-    font:
-        9pt Inconsolata,
-        monospace;
-    text-shadow: 0 0 5px #c8c8c8;
+.topics-button {
+    cursor: pointer;
+    width: 30px;
+    height: 30px;
+    border-radius: 20%;
+    box-shadow: 0 0 3px var(--color-accent);
+    background-color: var(--color-accent);
+    color: rgba(255, 255, 255, 0.75);
+    position: absolute;
+    left: 35%;
+    top: 75%;
+    z-index: 50;
+    margin-top: 5px;
+}
+
+.topics-icon-button {
+    width: 100%;
+    height: 100%;
+    padding: 0;
+}
+
+.topics-icon-size {
+    font-size: 16px;
     color: white;
-    padding: 10px;
-    max-width: 100%;
-    overflow-y: scroll;
-    white-space: pre-wrap;
 }
diff --git a/ui/src/app/editor/components/pipeline/pipeline.component.ts 
b/ui/src/app/editor/components/pipeline/pipeline.component.ts
index 71843f0692..7ff4bc3007 100644
--- a/ui/src/app/editor/components/pipeline/pipeline.component.ts
+++ b/ui/src/app/editor/components/pipeline/pipeline.component.ts
@@ -73,6 +73,7 @@ import { IdGeneratorService } from 
'../../../core-services/id-generator/id-gener
 @Component({
     selector: 'sp-pipeline',
     templateUrl: './pipeline.component.html',
+    styleUrls: ['./pipeline.component.scss'],
 })
 export class PipelineComponent implements OnInit, OnDestroy {
     @Input()
@@ -81,6 +82,9 @@ export class PipelineComponent implements OnInit, OnDestroy {
     @Input()
     rawPipelineModel: PipelineElementConfig[];
 
+    @Input()
+    pipelineElement: PipelineElementConfig;
+
     @Input()
     allElements: PipelineElementUnion[];
 
@@ -586,4 +590,8 @@ export class PipelineComponent implements OnInit, OnDestroy 
{
                     );
             });
     }
+
+    openTopicsDialog(pipelineElementConfig: PipelineElementConfig) {
+        this.editorService.openTopicsDialog(pipelineElementConfig);
+    }
 }
diff --git 
a/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
 
b/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
index 18f221cbfc..482d98e358 100644
--- 
a/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
+++ 
b/ui/src/app/editor/dialog/save-pipeline/save-pipeline-settings/save-pipeline-settings.component.html
@@ -95,6 +95,7 @@
                 >Show pipeline configuration as 
code</mat-expansion-panel-header
             >
             <sp-configuration-code-panel
+                *ngIf="compactPipeline"
                 [configuration]="compactPipeline"
                 maxHeight="none"
             >
diff --git a/ui/src/app/editor/services/editor.service.ts 
b/ui/src/app/editor/services/editor.service.ts
index 45ba82218d..0e0f19954b 100644
--- a/ui/src/app/editor/services/editor.service.ts
+++ b/ui/src/app/editor/services/editor.service.ts
@@ -40,6 +40,7 @@ import { DialogService, PanelType } from 
'@streampipes/shared-ui';
 import { map } from 'rxjs/operators';
 import { NGX_LOADING_BAR_IGNORED } from '@ngx-loading-bar/http-client';
 import { HelpComponent } from '../../core-ui/help/help.component';
+import { TopicsComponent } from 'src/app/core-ui/topics/topics.component';
 
 @Injectable({ providedIn: 'root' })
 export class EditorService {
@@ -175,6 +176,17 @@ export class EditorService {
         });
     }
 
+    openTopicsDialog(pipelineElementConfig: PipelineElementConfig) {
+        this.dialogService.open(TopicsComponent, {
+            panelType: PanelType.STANDARD_PANEL,
+            title: 'View Topics of ' + pipelineElementConfig.payload.name,
+            width: '70vw',
+            data: {
+                pipelineElement: pipelineElementConfig.payload,
+            },
+        });
+    }
+
     initiatePipelinePreview(
         pipeline: Pipeline,
     ): Observable<PipelinePreviewModel> {
diff --git 
a/ui/src/app/pipeline-details/dialogs/pipeline-code/pipeline-code-dialog.component.html
 
b/ui/src/app/pipeline-details/dialogs/pipeline-code/pipeline-code-dialog.component.html
index 2b89fa567e..9e17a966ea 100644
--- 
a/ui/src/app/pipeline-details/dialogs/pipeline-code/pipeline-code-dialog.component.html
+++ 
b/ui/src/app/pipeline-details/dialogs/pipeline-code/pipeline-code-dialog.component.html
@@ -20,6 +20,7 @@
     <div class="sp-dialog-content">
         <div fxFlex="100" fxLayout="column" class="p-10">
             <sp-configuration-code-panel
+                *ngIf="compactPipeline"
                 [configuration]="compactPipeline"
                 maxHeight="none"
             >
diff --git a/ui/src/app/pipeline-details/pipeline-details.module.ts 
b/ui/src/app/pipeline-details/pipeline-details.module.ts
index f05009a578..6eb5f6fb11 100644
--- a/ui/src/app/pipeline-details/pipeline-details.module.ts
+++ b/ui/src/app/pipeline-details/pipeline-details.module.ts
@@ -22,6 +22,7 @@ import { FormsModule, ReactiveFormsModule } from 
'@angular/forms';
 import { MatTabsModule } from '@angular/material/tabs';
 import { MatButtonModule } from '@angular/material/button';
 import { CommonModule } from '@angular/common';
+import { ClipboardModule } from '@angular/cdk/clipboard';
 import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
 import { PipelinePreviewComponent } from 
'./components/preview/pipeline-preview.component';
 import { EditorModule } from '../editor/editor.module';
@@ -62,6 +63,7 @@ import { PipelineCodeDialogComponent } from 
'./dialogs/pipeline-code/pipeline-co
         MatExpansionModule,
         MatSlideToggleModule,
         MatDivider,
+        ClipboardModule,
     ],
     declarations: [
         PipelineActionsComponent,

Reply via email to