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 9ff09d7729 refactor: Migrate pipeline-details & pipelines to control 
flow syntax (#3999)
9ff09d7729 is described below

commit 9ff09d77292b7d69da729ed2243b35b5fcb2c879
Author: Philipp Zehnder <[email protected]>
AuthorDate: Mon Dec 1 12:25:28 2025 +0100

    refactor: Migrate pipeline-details & pipelines to control flow syntax 
(#3999)
---
 .../actions/pipeline-actions.component.html        |  88 +++----
 ...pipeline-details-expansion-panel.component.html |  53 ++--
 .../status/pipeline-status.component.html          |  92 +++----
 .../pipeline-details-toolbar.component.html        |  44 ++--
 .../preview/pipeline-preview.component.html        |  62 ++---
 .../pipeline-code-dialog.component.html            |  45 ++--
 .../pipeline-logs-dialog.component.html            |  63 ++---
 .../pipeline-details.component.html                |  85 ++++---
 .../functions-logs/functions-logs.component.html   |  52 ++--
 .../functions-metrics.component.html               |  61 +++--
 .../pipeline-overview.component.html               | 277 +++++++++++----------
 .../delete-pipeline-dialog.component.html          | 156 ++++++------
 .../pipeline-notifications.component.html          |  43 ++--
 .../pipeline-status-dialog.component.html          | 155 ++++++------
 .../start-all-pipelines-dialog.component.html      | 168 +++++++------
 ui/src/app/pipelines/pipelines.component.html      | 119 ++++-----
 16 files changed, 818 insertions(+), 745 deletions(-)

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
index 8d126522ee..4f76dafa39 100644
--- 
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
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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"
@@ -22,32 +22,36 @@
     fxLayout="column"
     style="padding: 10px"
 >
-    <div fxLayout="row" *ngIf="!pipeline.running" fxLayoutAlign="start center">
-        <button
-            mat-icon-button
-            color="accent"
-            [matTooltip]="'Start Pipeline' | translate"
-            matTooltipPosition="above"
-            (click)="startPipeline()"
-            [disabled]="starting || !hasWritePipelinePrivileges"
-        >
-            <mat-icon>play_arrow</mat-icon>
-        </button>
-        <span>&nbsp;{{ 'Start pipeline' | translate }}</span>
-    </div>
-    <div fxLayout="row" *ngIf="pipeline.running" fxLayoutAlign="start center">
-        <button
-            mat-icon-button
-            color="accent"
-            [matTooltip]="'Stop Pipeline' | translate"
-            matTooltipPosition="above"
-            (click)="stopPipeline()"
-            [disabled]="stopping || !hasWritePipelinePrivileges"
-        >
-            <mat-icon>stop</mat-icon>
-        </button>
-        <span>&nbsp;{{ 'Stop pipeline' | translate }}</span>
-    </div>
+    @if (!pipeline.running) {
+        <div fxLayout="row" fxLayoutAlign="start center">
+            <button
+                mat-icon-button
+                color="accent"
+                [matTooltip]="'Start Pipeline' | translate"
+                matTooltipPosition="above"
+                (click)="startPipeline()"
+                [disabled]="starting || !hasWritePipelinePrivileges"
+            >
+                <mat-icon>play_arrow</mat-icon>
+            </button>
+            <span>&nbsp;{{ 'Start pipeline' | translate }}</span>
+        </div>
+    }
+    @if (pipeline.running) {
+        <div fxLayout="row" fxLayoutAlign="start center">
+            <button
+                mat-icon-button
+                color="accent"
+                [matTooltip]="'Stop Pipeline' | translate"
+                matTooltipPosition="above"
+                (click)="stopPipeline()"
+                [disabled]="stopping || !hasWritePipelinePrivileges"
+            >
+                <mat-icon>stop</mat-icon>
+            </button>
+            <span>&nbsp;{{ 'Stop pipeline' | translate }}</span>
+        </div>
+    }
     <div fxLayout="row" fxLayoutAlign="start center">
         <button
             mat-icon-button
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
index 02180ec11d..ff348f485b 100644
--- 
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
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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">
@@ -22,17 +22,16 @@
             {{ 'Logs' | translate }}
         </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>
+            @for (element of allPipelineElements; track element) {
+                <div 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>
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
index 120115b568..4f6da7aa99 100644
--- 
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
@@ -1,52 +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.
-  ~
-  -->
+~ 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">
+@if (pipelineStatus.length > 0) {
+    <div fxLayout="column" class="p-10">
+        @for (status of pipelineStatus; track status) {
+            <div fxFlex="100" fxLayout="column" fxLayoutGap="10px">
+                <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>
+}
+@if (pipelineStatus.length === 0) {
     <div
-        fxFlex="100"
         fxLayout="column"
-        fxLayoutGap="10px"
-        *ngFor="let status of pipelineStatus"
+        fxLayoutAlign="center center"
+        style="min-height: 100px; padding: 5px; padding-left: 15px"
     >
-        <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>
+        ({{ 'no status information available' | translate }})
     </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' | translate }})
-</div>
+}
diff --git 
a/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.html
 
b/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.html
index 7acfa2659c..7e10ef1226 100644
--- 
a/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.html
+++ 
b/ui/src/app/pipeline-details/components/pipeline-details-toolbar/pipeline-details-toolbar.component.html
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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 center">
     <button
@@ -26,12 +26,12 @@
     >
         <div fxLayoutAlign="start center" fxLayout="row">
             <i class="material-icons">visibility</i>
-            <span *ngIf="!previewModeActive"
-                >&nbsp;{{ 'Enable live preview' | translate }}</span
-            >
-            <span *ngIf="previewModeActive"
-                >&nbsp;{{ 'Disable live preview' | translate }}</span
-            >
+            @if (!previewModeActive) {
+                <span>&nbsp;{{ 'Enable live preview' | translate }}</span>
+            }
+            @if (previewModeActive) {
+                <span>&nbsp;{{ 'Disable live preview' | translate }}</span>
+            }
         </div>
     </button>
     @if (hasPipelineWritePrivileges) {
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 9a8ea603f9..8d3ee9bef0 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
@@ -1,37 +1,39 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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="outer-assembly-preview" fxFlex="100">
     <div class="outerAssembly" fxFlex="100">
-        <sp-pipeline-assembly-drawing-area
-            #pipelineDrawingAreaComponent
-            *ngIf="rawPipelineModel"
-            fxFlex="100"
-            style="position: relative"
-            [jsplumbBridge]="jsPlumbBridge"
-            [metricsInfo]="metricsInfo"
-            [rawPipelineModel]="rawPipelineModel"
-            [pipelineCanvasMetadata]="pipelineCanvasMetadata"
-            [pipelineCanvasMetadataAvailable]="
-                pipelineCanvasMetadata?.pipelineElementMetadata !== undefined
-            "
-            [readonly]="true"
-        ></sp-pipeline-assembly-drawing-area>
+        @if (rawPipelineModel) {
+            <sp-pipeline-assembly-drawing-area
+                #pipelineDrawingAreaComponent
+                fxFlex="100"
+                style="position: relative"
+                [jsplumbBridge]="jsPlumbBridge"
+                [metricsInfo]="metricsInfo"
+                [rawPipelineModel]="rawPipelineModel"
+                [pipelineCanvasMetadata]="pipelineCanvasMetadata"
+                [pipelineCanvasMetadataAvailable]="
+                    pipelineCanvasMetadata?.pipelineElementMetadata !==
+                    undefined
+                "
+                [readonly]="true"
+            ></sp-pipeline-assembly-drawing-area>
+        }
     </div>
     <ng-content></ng-content>
 </div>
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 fb06be9fb0..7feb5064a1 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
@@ -1,30 +1,31 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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" class="p-10">
-            <sp-configuration-code-panel
-                *ngIf="compactPipeline"
-                [configuration]="compactPipeline"
-                maxHeight="none"
-            >
-            </sp-configuration-code-panel>
+            @if (compactPipeline) {
+                <sp-configuration-code-panel
+                    [configuration]="compactPipeline"
+                    maxHeight="none"
+                >
+                </sp-configuration-code-panel>
+            }
         </div>
     </div>
     <mat-divider></mat-divider>
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
index 18b2c5a12d..d7a07fd1e6 100644
--- 
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
@@ -1,38 +1,43 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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" class="p-10">
-                <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' | translate }})
-                    </h5>
-                </div>
+                @for (logEntry of logInfo; track logEntry) {
+                    <div>
+                        @if (logEntry.errorMessage) {
+                            <sp-exception-message
+                                [message]="logEntry.errorMessage"
+                                [messageTimestamp]="logEntry.timestamp"
+                                class="mt-10"
+                            ></sp-exception-message>
+                        }
+                    </div>
+                }
+                @if (logInfo.length === 0) {
+                    <div>
+                        <h5 class="text-center">
+                            ({{ 'no log messages available' | translate }})
+                        </h5>
+                    </div>
+                }
             </div>
         </div>
     </div>
diff --git a/ui/src/app/pipeline-details/pipeline-details.component.html 
b/ui/src/app/pipeline-details/pipeline-details.component.html
index 277b64b496..1d775f9182 100644
--- a/ui/src/app/pipeline-details/pipeline-details.component.html
+++ b/ui/src/app/pipeline-details/pipeline-details.component.html
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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"
@@ -35,30 +35,35 @@
         </sp-pipeline-details-toolbar>
     </div>
     <div fxFlex="100" fxLayout="column">
-        <div *ngIf="pipelineNotFound">
-            <sp-warning-box color="primary">{{
-                'The desired pipeline was not found!' | translate
-            }}</sp-warning-box>
-        </div>
-
-        <sp-pipeline-preview
-            #pipelinePreviewComponent
-            [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"
-                    (reloadPipelineEmitter)="loadPipeline()"
-                    [logInfo]="logInfo"
-                    [pipeline]="pipeline"
-                >
-                </sp-pipeline-details-expansion-panel>
+        @if (pipelineNotFound) {
+            <div>
+                <sp-warning-box color="primary">{{
+                    'The desired pipeline was not found!' | translate
+                }}</sp-warning-box>
             </div>
-        </sp-pipeline-preview>
+        }
+
+        @if (pipelineAvailable) {
+            <sp-pipeline-preview
+                #pipelinePreviewComponent
+                [metricsInfo]="metricsInfo"
+                [pipeline]="pipeline"
+                [pipelineCanvasMetadata]="pipelineCanvasMetadata"
+                (selectedElementEmitter)="selectElement($event)"
+                style="display: flex; flex: 1 1"
+            >
+                <div class="expansion-panel" fxFlex="100" fxLayout="column">
+                    <sp-pipeline-details-expansion-panel
+                        [hasWritePipelinePrivileges]="
+                            hasPipelineWritePrivileges
+                        "
+                        (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/pipelines/components/functions-overview/functions-logs/functions-logs.component.html
 
b/ui/src/app/pipelines/components/functions-overview/functions-logs/functions-logs.component.html
index 2882e6ce7f..582cc3548e 100644
--- 
a/ui/src/app/pipelines/components/functions-overview/functions-logs/functions-logs.component.html
+++ 
b/ui/src/app/pipelines/components/functions-overview/functions-logs/functions-logs.component.html
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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"
@@ -33,13 +33,15 @@
             <i class="material-icons">refresh</i>
         </button>
     </div>
-    <div fxFlex="100" fxLayout="column" *ngIf="activeFunction && contentReady">
-        <sp-simple-logs
-            [elementName]="activeFunction.functionId.id"
-            [logs]="logs"
-            fxFlex="100"
-            fxLayout="column"
-        >
-        </sp-simple-logs>
-    </div>
+    @if (activeFunction && contentReady) {
+        <div fxFlex="100" fxLayout="column">
+            <sp-simple-logs
+                [elementName]="activeFunction.functionId.id"
+                [logs]="logs"
+                fxFlex="100"
+                fxLayout="column"
+            >
+            </sp-simple-logs>
+        </div>
+    }
 </sp-basic-nav-tabs>
diff --git 
a/ui/src/app/pipelines/components/functions-overview/functions-metrics/functions-metrics.component.html
 
b/ui/src/app/pipelines/components/functions-overview/functions-metrics/functions-metrics.component.html
index 1a2524eae7..fceb4f3f14 100644
--- 
a/ui/src/app/pipelines/components/functions-overview/functions-metrics/functions-metrics.component.html
+++ 
b/ui/src/app/pipelines/components/functions-overview/functions-metrics/functions-metrics.component.html
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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"
@@ -33,16 +33,23 @@
             <i class="material-icons">refresh</i>
         </button>
     </div>
-    <div fxFlex="100" fxLayout="column" *ngIf="activeFunction && contentReady">
-        <div *ngFor="let messagesIn of metrics.messagesIn | keyvalue">
-            <sp-simple-metrics
-                [elementName]="streamNames[messagesIn.key]"
-                lastPublishedLabel="Last consumed message"
-                statusValueLabel="Consumed messages"
-                [lastTimestamp]="messagesIn.value.lastTimestamp"
-                [statusValue]="messagesIn.value.counter"
-            >
-            </sp-simple-metrics>
+    @if (activeFunction && contentReady) {
+        <div fxFlex="100" fxLayout="column">
+            @for (
+                messagesIn of metrics.messagesIn | keyvalue;
+                track messagesIn
+            ) {
+                <div>
+                    <sp-simple-metrics
+                        [elementName]="streamNames[messagesIn.key]"
+                        lastPublishedLabel="Last consumed message"
+                        statusValueLabel="Consumed messages"
+                        [lastTimestamp]="messagesIn.value.lastTimestamp"
+                        [statusValue]="messagesIn.value.counter"
+                    >
+                    </sp-simple-metrics>
+                </div>
+            }
         </div>
-    </div>
+    }
 </sp-basic-nav-tabs>
diff --git 
a/ui/src/app/pipelines/components/pipeline-overview/pipeline-overview.component.html
 
b/ui/src/app/pipelines/components/pipeline-overview/pipeline-overview.component.html
index 6ada52ff09..91d2fccbd6 100644
--- 
a/ui/src/app/pipelines/components/pipeline-overview/pipeline-overview.component.html
+++ 
b/ui/src/app/pipelines/components/pipeline-overview/pipeline-overview.component.html
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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-table
     [dataSource]="dataSource"
@@ -32,69 +32,68 @@
         <td mat-cell *matCellDef="let pipeline">
             <div>
                 <div fxLayout="row" fxLayoutAlign="start center" 
fxFlex="150px">
-                    <div
-                        data-cy="status-pipeline-green"
-                        *ngIf="
-                            pipeline.running && pipeline.healthStatus === 'OK'
-                        "
-                        class="light light-green"
-                    ></div>
-                    <div
-                        *ngIf="
-                            pipeline.running &&
-                            pipeline.healthStatus === 'REQUIRES_ATTENTION'
-                        "
-                        class="light light-yellow"
-                    ></div>
-                    <div
-                        *ngIf="
-                            pipeline.running &&
-                            pipeline.healthStatus === 'FAILURE'
-                        "
-                        class="light light-red"
-                    ></div>
-                    <div
-                        *ngIf="!pipeline.running"
-                        class="light light-neutral"
-                        [matTooltip]="'Stopped' | translate"
-                    ></div>
+                    @if (pipeline.running && pipeline.healthStatus === 'OK') {
+                        <div
+                            data-cy="status-pipeline-green"
+                            class="light light-green"
+                        ></div>
+                    }
+                    @if (
+                        pipeline.running &&
+                        pipeline.healthStatus === 'REQUIRES_ATTENTION'
+                    ) {
+                        <div class="light light-yellow"></div>
+                    }
+                    @if (
+                        pipeline.running && pipeline.healthStatus === 'FAILURE'
+                    ) {
+                        <div class="light light-red"></div>
+                    }
+                    @if (!pipeline.running) {
+                        <div
+                            class="light light-neutral"
+                            [matTooltip]="'Stopped' | translate"
+                        ></div>
+                    }
                     <div class="notification-icon">
-                        <button
-                            class="ml-10"
-                            mat-icon-button
-                            [disabled]="!hasPipelineWritePrivileges"
-                            (click)="
-                                openPipelineNotificationsDialog(pipeline);
-                                $event.stopPropagation()
-                            "
-                            *ngIf="pipeline.pipelineNotifications.length > 0"
-                            matTooltip="{{
-                                pipeline.pipelineNotifications.length
-                            }} notification{{
-                                pipeline.pipelineNotifications.length > 1
-                                    ? 's'
-                                    : ''
-                            }}"
-                            data-cy="pipeline-warning-icon"
-                        >
-                            <i class="material-icons pipeline-notification"
-                                >warning</i
+                        @if (pipeline.pipelineNotifications.length > 0) {
+                            <button
+                                class="ml-10"
+                                mat-icon-button
+                                [disabled]="!hasPipelineWritePrivileges"
+                                (click)="
+                                    openPipelineNotificationsDialog(pipeline);
+                                    $event.stopPropagation()
+                                "
+                                matTooltip="{{
+                                    pipeline.pipelineNotifications.length
+                                }} notification{{
+                                    pipeline.pipelineNotifications.length > 1
+                                        ? 's'
+                                        : ''
+                                }}"
+                                data-cy="pipeline-warning-icon"
                             >
-                        </button>
+                                <i class="material-icons pipeline-notification"
+                                    >warning</i
+                                >
+                            </button>
+                        }
                     </div>
                     <div
                         class="ml-10 notification-icon"
                         data-cy="pipeline-sync-problem-icon"
                     >
-                        <mat-icon
-                            color="warn"
-                            [matTooltip]="
-                                'Invalid pipeline: Modify to fix problems'
-                                    | translate
-                            "
-                            *ngIf="!pipeline.valid"
-                            >sync_problem
-                        </mat-icon>
+                        @if (!pipeline.valid) {
+                            <mat-icon
+                                color="warn"
+                                [matTooltip]="
+                                    'Invalid pipeline: Modify to fix problems'
+                                        | translate
+                                "
+                                >sync_problem
+                            </mat-icon>
+                        }
                     </div>
                 </div>
             </div>
@@ -104,48 +103,50 @@
         <th mat-header-cell *matHeaderCellDef>{{ 'Start' | translate }}</th>
         <td mat-cell *matCellDef="let pipeline">
             <div fxLayoutAlign="start start">
-                <button
-                    color="accent"
-                    mat-icon-button
-                    [matTooltip]="'Start pipeline' | translate"
-                    matTooltipPosition="above"
-                    data-cy="start-pipeline-button"
-                    (click)="
-                        pipelineOperationsService.startPipeline(
-                            pipeline._id,
-                            refreshPipelinesEmitter,
-                            toggleRunningOperation
-                        );
-                        $event.stopPropagation()
-                    "
-                    [disabled]="
-                        !hasPipelineWritePrivileges ||
-                        starting ||
-                        !pipeline.valid
-                    "
-                    *ngIf="!pipeline.running"
-                >
-                    <i class="material-icons">play_arrow</i>
-                </button>
-                <button
-                    color="accent"
-                    mat-icon-button
-                    [matTooltip]="'Stop pipeline' | translate"
-                    matTooltipPosition="above"
-                    data-cy="stop-pipeline-button"
-                    (click)="
-                        pipelineOperationsService.stopPipeline(
-                            pipeline._id,
-                            refreshPipelinesEmitter,
-                            toggleRunningOperation
-                        );
-                        $event.stopPropagation()
-                    "
-                    [disabled]="!hasPipelineWritePrivileges || stopping"
-                    *ngIf="pipeline.running"
-                >
-                    <i class="material-icons">stop</i>
-                </button>
+                @if (!pipeline.running) {
+                    <button
+                        color="accent"
+                        mat-icon-button
+                        [matTooltip]="'Start pipeline' | translate"
+                        matTooltipPosition="above"
+                        data-cy="start-pipeline-button"
+                        (click)="
+                            pipelineOperationsService.startPipeline(
+                                pipeline._id,
+                                refreshPipelinesEmitter,
+                                toggleRunningOperation
+                            );
+                            $event.stopPropagation()
+                        "
+                        [disabled]="
+                            !hasPipelineWritePrivileges ||
+                            starting ||
+                            !pipeline.valid
+                        "
+                    >
+                        <i class="material-icons">play_arrow</i>
+                    </button>
+                }
+                @if (pipeline.running) {
+                    <button
+                        color="accent"
+                        mat-icon-button
+                        [matTooltip]="'Stop pipeline' | translate"
+                        matTooltipPosition="above"
+                        data-cy="stop-pipeline-button"
+                        (click)="
+                            pipelineOperationsService.stopPipeline(
+                                pipeline._id,
+                                refreshPipelinesEmitter,
+                                toggleRunningOperation
+                            );
+                            $event.stopPropagation()
+                        "
+                        [disabled]="!hasPipelineWritePrivileges || stopping"
+                    >
+                        <i class="material-icons">stop</i>
+                    </button>
+                }
             </div>
         </td>
     </ng-container>
@@ -179,15 +180,16 @@
             <mat-icon>visibility</mat-icon>
             <span>{{ 'Show' | translate }}</span>
         </button>
-        <button
-            mat-menu-item
-            *ngIf="hasPipelineWritePrivileges"
-            (click)="pipelineOperationsService.modifyPipeline(element._id)"
-            data-cy="modify-pipeline-btn"
-        >
-            <mat-icon>mode_edit</mat-icon>
-            <span>{{ 'Edit' | translate }}</span>
-        </button>
+        @if (hasPipelineWritePrivileges) {
+            <button
+                mat-menu-item
+                (click)="pipelineOperationsService.modifyPipeline(element._id)"
+                data-cy="modify-pipeline-btn"
+            >
+                <mat-icon>mode_edit</mat-icon>
+                <span>{{ 'Edit' | translate }}</span>
+            </button>
+        }
         <button
             mat-menu-item
             (click)="
@@ -201,19 +203,20 @@
             <mat-icon>share</mat-icon>
             <span>{{ 'Manage permissions' | translate }}</span>
         </button>
-        <button
-            mat-menu-item
-            *ngIf="hasPipelineWritePrivileges"
-            (click)="
-                pipelineOperationsService.showDeleteDialog(
-                    element,
-                    refreshPipelinesEmitter
-                )
-            "
-            data-cy="delete-pipeline"
-        >
-            <mat-icon>delete</mat-icon>
-            <span>{{ 'Delete' | translate }}</span>
-        </button>
+        @if (hasPipelineWritePrivileges) {
+            <button
+                mat-menu-item
+                (click)="
+                    pipelineOperationsService.showDeleteDialog(
+                        element,
+                        refreshPipelinesEmitter
+                    )
+                "
+                data-cy="delete-pipeline"
+            >
+                <mat-icon>delete</mat-icon>
+                <span>{{ 'Delete' | translate }}</span>
+            </button>
+        }
     </ng-template>
 </sp-table>
diff --git 
a/ui/src/app/pipelines/dialog/delete-pipeline/delete-pipeline-dialog.component.html
 
b/ui/src/app/pipelines/dialog/delete-pipeline/delete-pipeline-dialog.component.html
index 37507cc451..37d3339e76 100644
--- 
a/ui/src/app/pipelines/dialog/delete-pipeline/delete-pipeline-dialog.component.html
+++ 
b/ui/src/app/pipelines/dialog/delete-pipeline/delete-pipeline-dialog.component.html
@@ -1,84 +1,98 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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">
-        <div *ngIf="!isInProgress" fxLayout="column">
-            <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column">
-                <b
-                    ><h4>
-                        {{
-                            'Do you really want to delete pipeline' | translate
-                        }}
-                        {{ pipeline.name }}?
-                    </h4></b
+        @if (!isInProgress) {
+            <div fxLayout="column">
+                <div
+                    fxFlex="100"
+                    fxLayoutAlign="center center"
+                    fxLayout="column"
                 >
-                <b
-                    ><h4 *ngIf="pipeline.running">
-                        {{ 'This pipeline is still running.' | translate }}
-                    </h4></b
-                >
-                <b
-                    ><h5>
-                        {{ 'This operation cannot be undone.' | translate }}
-                    </h5></b
+                    <b
+                        ><h4>
+                            {{
+                                'Do you really want to delete pipeline'
+                                    | translate
+                            }}
+                            {{ pipeline.name }}?
+                        </h4></b
+                    >
+                    <b>
+                        @if (pipeline.running) {
+                            <h4>
+                                {{
+                                    'This pipeline is still running.'
+                                        | translate
+                                }}
+                            </h4>
+                        }
+                    </b>
+                    <b
+                        ><h5>
+                            {{ 'This operation cannot be undone.' | translate 
}}
+                        </h5></b
+                    >
+                </div>
+                <div
+                    fxFlex="100"
+                    fxLayoutAlign="center center"
+                    fxLayout="column"
                 >
+                    @if (!pipeline.running) {
+                        <button
+                            mat-button
+                            mat-flat-button
+                            color="accent"
+                            (click)="deletePipeline()"
+                        >
+                            {{ 'Delete pipeline' | translate }}
+                        </button>
+                    }
+                    @if (pipeline.running) {
+                        <button
+                            mat-button
+                            mat-flat-button
+                            color="accent"
+                            (click)="stopAndDeletePipeline()"
+                            data-cy="sp-pipeline-stop-and-delete"
+                        >
+                            {{ 'Stop and delete pipeline' | translate }}
+                        </button>
+                    }
+                </div>
             </div>
-
+        }
+        @if (isInProgress) {
             <div fxFlex="100" fxLayoutAlign="center center" fxLayout="column">
-                <button
-                    mat-button
-                    mat-flat-button
-                    color="accent"
-                    *ngIf="!pipeline.running"
-                    (click)="deletePipeline()"
-                >
-                    {{ 'Delete pipeline' | translate }}
-                </button>
-                <button
-                    mat-button
-                    mat-flat-button
-                    color="accent"
-                    *ngIf="pipeline.running"
-                    (click)="stopAndDeletePipeline()"
-                    data-cy="sp-pipeline-stop-and-delete"
+                <div fxLayout="row" fxLayoutAlign="space-around">
+                    <mat-spinner
+                        [diameter]="50"
+                        [mode]="'indeterminate'"
+                        color="accent"
+                    ></mat-spinner>
+                </div>
+                <b
+                    ><h4>{{ currentStatus }}</h4></b
                 >
-                    {{ 'Stop and delete pipeline' | translate }}
-                </button>
-            </div>
-        </div>
-        <div
-            fxFlex="100"
-            fxLayoutAlign="center center"
-            fxLayout="column"
-            *ngIf="isInProgress"
-        >
-            <div fxLayout="row" fxLayoutAlign="space-around">
-                <mat-spinner
-                    [diameter]="50"
-                    [mode]="'indeterminate'"
-                    color="accent"
-                ></mat-spinner>
             </div>
-            <b
-                ><h4>{{ currentStatus }}</h4></b
-            >
-        </div>
+        }
     </div>
     <mat-divider></mat-divider>
     <div class="sp-dialog-actions actions-align-right">
diff --git 
a/ui/src/app/pipelines/dialog/pipeline-notifications/pipeline-notifications.component.html
 
b/ui/src/app/pipelines/dialog/pipeline-notifications/pipeline-notifications.component.html
index 34e92a6da1..1bf3b33a1a 100644
--- 
a/ui/src/app/pipelines/dialog/pipeline-notifications/pipeline-notifications.component.html
+++ 
b/ui/src/app/pipelines/dialog/pipeline-notifications/pipeline-notifications.component.html
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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" fxLayout="column">
     <div class="sp-dialog-content p-15" fxFlex="100" fxLayout="column">
@@ -25,9 +25,14 @@
             }}
         </div>
         <div class="log-message" fxFlex="100" fxLayout="column">
-            <span *ngFor="let notification of pipeline.pipelineNotifications">
-                <p>{{ notification }}</p>
-            </span>
+            @for (
+                notification of pipeline.pipelineNotifications;
+                track notification
+            ) {
+                <span>
+                    <p>{{ notification }}</p>
+                </span>
+            }
         </div>
     </div>
     <mat-divider></mat-divider>
diff --git 
a/ui/src/app/pipelines/dialog/pipeline-status/pipeline-status-dialog.component.html
 
b/ui/src/app/pipelines/dialog/pipeline-status/pipeline-status-dialog.component.html
index b12504cab4..cd69fe8960 100644
--- 
a/ui/src/app/pipelines/dialog/pipeline-status/pipeline-status-dialog.component.html
+++ 
b/ui/src/app/pipelines/dialog/pipeline-status/pipeline-status-dialog.component.html
@@ -1,19 +1,19 @@
 <!-- ~ 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.
-  ~
-  -->
+~ 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">
@@ -23,80 +23,83 @@
             fxLayoutAlign="center center"
             fxFlex="100"
         >
-            <div
-                fxFlex="100"
-                fxLayoutAlign="center center"
-                fxLayout="column"
-                *ngIf="operationInProgress"
-            >
-                <div fxFlex="100" fxLayoutAlign="center center">
-                    <mat-spinner
-                        color="accent"
-                        [diameter]="30"
-                        fxLayoutAlign="center"
-                        style="margin: 10px 0 5px 0"
-                    >
-                        @if (action === 0) {
-                            {{ 'Starting' | translate }}
-                        } @else {
-                            {{ 'Stopping' | translate }}
-                        }
-                    </mat-spinner>
-                </div>
+            @if (operationInProgress) {
                 <div
                     fxFlex="100"
                     fxLayoutAlign="center center"
                     fxLayout="column"
                 >
-                    <span class="success-message">
-                        @if (action === 0) {
-                            {{
-                                'Please wait while the pipeline is starting'
-                                    | translate
-                            }}
-                        } @else {
-                            {{
-                                'Please wait while the pipeline is stopping'
-                                    | translate
-                            }}
-                        }
-                    </span>
+                    <div fxFlex="100" fxLayoutAlign="center center">
+                        <mat-spinner
+                            color="accent"
+                            [diameter]="30"
+                            fxLayoutAlign="center"
+                            style="margin: 10px 0 5px 0"
+                        >
+                            @if (action === 0) {
+                                {{ 'Starting' | translate }}
+                            } @else {
+                                {{ 'Stopping' | translate }}
+                            }
+                        </mat-spinner>
+                    </div>
+                    <div
+                        fxFlex="100"
+                        fxLayoutAlign="center center"
+                        fxLayout="column"
+                    >
+                        <span class="success-message">
+                            @if (action === 0) {
+                                {{
+                                    'Please wait while the pipeline is 
starting'
+                                        | translate
+                                }}
+                            } @else {
+                                {{
+                                    'Please wait while the pipeline is 
stopping'
+                                        | translate
+                                }}
+                            }
+                        </span>
+                    </div>
                 </div>
-            </div>
+            }
 
-            <div
-                *ngIf="!operationInProgress && forceStopActive"
-                fxLayout="column"
-                fxLayoutAlign="center center"
-                fxFlex="100"
-            >
+            @if (!operationInProgress && forceStopActive) {
                 <div
-                    class="success-message"
-                    fxFlex="100"
-                    fxLayoutAlign="center center"
                     fxLayout="column"
+                    fxLayoutAlign="center center"
+                    fxFlex="100"
                 >
-                    <div fxLayout="row">
-                        <mat-icon color="accent">done</mat-icon>
-                        <span
-                            >&nbsp;{{
-                                'Forced stop successful' | translate
-                            }}</span
-                        >
+                    <div
+                        class="success-message"
+                        fxFlex="100"
+                        fxLayoutAlign="center center"
+                        fxLayout="column"
+                    >
+                        <div fxLayout="row">
+                            <mat-icon color="accent">done</mat-icon>
+                            <span
+                                >&nbsp;{{
+                                    'Forced stop successful' | translate
+                                }}</span
+                            >
+                        </div>
                     </div>
                 </div>
-            </div>
+            }
 
-            <sp-pipeline-started-status
-                *ngIf="!operationInProgress && !forceStopActive"
-                [pipelineOperationStatus]="pipelineOperationStatus"
-                [action]="action"
-                (forceStopPipelineEmitter)="forceStopPipeline()"
-                fxLayout="column"
-                fxLayoutAlign="center center"
-                fxFlex="100"
-            >
-            </sp-pipeline-started-status>
+            @if (!operationInProgress && !forceStopActive) {
+                <sp-pipeline-started-status
+                    [pipelineOperationStatus]="pipelineOperationStatus"
+                    [action]="action"
+                    (forceStopPipelineEmitter)="forceStopPipeline()"
+                    fxLayout="column"
+                    fxLayoutAlign="center center"
+                    fxFlex="100"
+                >
+                </sp-pipeline-started-status>
+            }
         </div>
     </div>
 
diff --git 
a/ui/src/app/pipelines/dialog/start-all-pipelines/start-all-pipelines-dialog.component.html
 
b/ui/src/app/pipelines/dialog/start-all-pipelines/start-all-pipelines-dialog.component.html
index c621eeab3a..966ff795be 100644
--- 
a/ui/src/app/pipelines/dialog/start-all-pipelines/start-all-pipelines-dialog.component.html
+++ 
b/ui/src/app/pipelines/dialog/start-all-pipelines/start-all-pipelines-dialog.component.html
@@ -1,84 +1,104 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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">
         <div>
-            <div
-                fxFlex="100"
-                class="md-dialog-content"
-                style="padding: 20px"
-                *ngIf="page === 'preview'"
-            >
-                <h4 *ngIf="action">
-                    {{
-                        'You are about to start the following pipelines:'
-                            | translate
-                    }}
-                </h4>
-                <h4 *ngIf="!action">
-                    {{
-                        'You are about to stop the following pipelines:'
-                            | translate
-                    }}
-                </h4>
-                <div *ngFor="let pipeline of pipelinesToModify">
-                    <h5>{{ pipeline.name }}</h5>
+            @if (page === 'preview') {
+                <div
+                    fxFlex="100"
+                    class="md-dialog-content"
+                    style="padding: 20px"
+                >
+                    @if (action) {
+                        <h4>
+                            {{
+                                'You are about to start the following 
pipelines:'
+                                    | translate
+                            }}
+                        </h4>
+                    }
+                    @if (!action) {
+                        <h4>
+                            {{
+                                'You are about to stop the following 
pipelines:'
+                                    | translate
+                            }}
+                        </h4>
+                    }
+                    @for (pipeline of pipelinesToModify; track pipeline) {
+                        <div>
+                            <h5>{{ pipeline.name }}</h5>
+                        </div>
+                    }
+                    <h5>
+                        <b>{{
+                            'Press Next to start the process.' | translate
+                        }}</b>
+                    </h5>
                 </div>
-                <h5>
-                    <b>{{ 'Press Next to start the process.' | translate }}</b>
-                </h5>
-            </div>
-            <div
-                fxFlex="100"
-                class="md-dialog-content"
-                style="padding: 20px"
-                *ngIf="page === 'installation'"
-            >
-                <div *ngFor="let status of installationStatus">
-                    <h4>
-                        @if (action) {
-                            {{ 'Starting pipeline ' | translate }}
-                        } @else {
-                            {{ 'Stopping pipeline' | translate }}
-                        }
-                        {{ status.id + 1 }} {{ 'of' | translate }}
-                        {{ pipelinesToModify.length }} ({{ status.name }})...{{
-                            status.status
-                        }}
-                    </h4>
+            }
+            @if (page === 'installation') {
+                <div
+                    fxFlex="100"
+                    class="md-dialog-content"
+                    style="padding: 20px"
+                >
+                    @for (status of installationStatus; track status) {
+                        <div>
+                            <h4>
+                                @if (action) {
+                                    {{ 'Starting pipeline ' | translate }}
+                                } @else {
+                                    {{ 'Stopping pipeline' | translate }}
+                                }
+                                {{ status.id + 1 }} {{ 'of' | translate }}
+                                {{ pipelinesToModify.length }} ({{
+                                    status.name
+                                }})...{{ status.status }}
+                            </h4>
+                        </div>
+                    }
+                    @if (pipelinesToModify.length === 0) {
+                        <div>
+                            @if (action) {
+                                <h4></h4>
+                            }
+                            @if (!action) {
+                                <h4>
+                                    {{
+                                        'Sorry, there are no pipelines that 
are currently idle.'
+                                            | translate
+                                    }}
+                                </h4>
+                            }
+                            @if (action) {
+                                <h4>
+                                    {{
+                                        'Sorry, there are no pipelines that 
are currently running.'
+                                            | translate
+                                    }}
+                                </h4>
+                            }
+                        </div>
+                    }
                 </div>
-                <div *ngIf="pipelinesToModify.length === 0">
-                    <h4 *ngIf="action"></h4>
-                    <h4 *ngIf="!action">
-                        {{
-                            'Sorry, there are no pipelines that are currently 
idle.'
-                                | translate
-                        }}
-                    </h4>
-                    <h4 *ngIf="action">
-                        {{
-                            'Sorry, there are no pipelines that are currently 
running.'
-                                | translate
-                        }}
-                    </h4>
-                </div>
-            </div>
+            }
         </div>
     </div>
     <mat-divider></mat-divider>
diff --git a/ui/src/app/pipelines/pipelines.component.html 
b/ui/src/app/pipelines/pipelines.component.html
index 5ec8323d18..c6d9841754 100644
--- a/ui/src/app/pipelines/pipelines.component.html
+++ b/ui/src/app/pipelines/pipelines.component.html
@@ -1,20 +1,20 @@
 <!--
-  ~ 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.
-  ~
-  -->
+~ 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]="false" [padding]="true">
     <div
@@ -25,38 +25,41 @@
         fxLayoutGap="10px"
         class="pl-10"
     >
-        <button
-            mat-button
-            mat-flat-button
-            color="accent"
-            *ngIf="hasPipelineWritePrivileges"
-            (click)="navigateToPipelineEditor()"
-            data-cy="pipelines-navigate-to-editor"
-        >
-            <i class="material-icons">add</i>&nbsp;{{
-                'New Pipeline' | translate
-            }}
-        </button>
-        <button
-            mat-flat-button
-            class="mat-basic"
-            (click)="startAllPipelines(true)"
-            [disabled]="checkCurrentSelectionStatus(false)"
-            *ngIf="hasPipelineWritePrivileges"
-        >
-            <mat-icon>play_arrow</mat-icon>
-            <span>{{ 'Start All Pipelines' | translate }}</span>
-        </button>
-        <button
-            mat-flat-button
-            class="mat-basic"
-            (click)="startAllPipelines(false)"
-            [disabled]="checkCurrentSelectionStatus(true)"
-            *ngIf="hasPipelineWritePrivileges"
-        >
-            <mat-icon>stop</mat-icon>
-            <span>{{ 'Stop all pipelines' | translate }}</span>
-        </button>
+        @if (hasPipelineWritePrivileges) {
+            <button
+                mat-button
+                mat-flat-button
+                color="accent"
+                (click)="navigateToPipelineEditor()"
+                data-cy="pipelines-navigate-to-editor"
+            >
+                <i class="material-icons">add</i>&nbsp;{{
+                    'New Pipeline' | translate
+                }}
+            </button>
+        }
+        @if (hasPipelineWritePrivileges) {
+            <button
+                mat-flat-button
+                class="mat-basic"
+                (click)="startAllPipelines(true)"
+                [disabled]="checkCurrentSelectionStatus(false)"
+            >
+                <mat-icon>play_arrow</mat-icon>
+                <span>{{ 'Start All Pipelines' | translate }}</span>
+            </button>
+        }
+        @if (hasPipelineWritePrivileges) {
+            <button
+                mat-flat-button
+                class="mat-basic"
+                (click)="startAllPipelines(false)"
+                [disabled]="checkCurrentSelectionStatus(true)"
+            >
+                <mat-icon>stop</mat-icon>
+                <span>{{ 'Stop all pipelines' | translate }}</span>
+            </button>
+        }
         <span fxFlex></span>
         <button
             mat-icon-button
@@ -84,11 +87,12 @@
             ></sp-basic-header-title-component>
             <div fxFlex="100" fxLayout="row" fxLayoutAlign="center start">
                 <div fxFlex="100">
-                    <sp-pipeline-overview
-                        [pipelines]="filteredPipelines"
-                        (refreshPipelinesEmitter)="getPipelines()"
-                        *ngIf="pipelinesReady"
-                    ></sp-pipeline-overview>
+                    @if (pipelinesReady) {
+                        <sp-pipeline-overview
+                            [pipelines]="filteredPipelines"
+                            (refreshPipelinesEmitter)="getPipelines()"
+                        ></sp-pipeline-overview>
+                    }
                 </div>
             </div>
             <div fxFlex="100" fxLayout="column" style="margin-top: 20px">
@@ -97,11 +101,10 @@
                 ></sp-basic-header-title-component>
                 <div fxFlex="100" fxLayout="row" fxLayoutAlign="center start">
                     <div fxFlex="100">
-                        <sp-functions-overview
-                            [functions]="functions"
-                            *ngIf="functionsReady"
-                        >
-                        </sp-functions-overview>
+                        @if (functionsReady) {
+                            <sp-functions-overview [functions]="functions">
+                            </sp-functions-overview>
+                        }
                     </div>
                 </div>
             </div>

Reply via email to