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

riemer pushed a commit to branch add-reusable-alert-banner
in repository https://gitbox.apache.org/repos/asf/streampipes.git

commit 921ac7ec369fcb8fb7e022e6fd55f36da67f9179
Author: Dominik Riemer <[email protected]>
AuthorDate: Fri Dec 5 22:48:35 2025 +0100

    style: Add reusable alert banner
---
 .../src/lib/model/types/alert-type.ts}             |  10 +-
 .../platform-services/src/public-api.ts            |   1 +
 .../alert-banner.component.html}                   |  13 +-
 .../alert-banner/alert-banner.component.scss       |  77 ++++++++
 .../alert-banner/alert-banner.component.ts         |  64 +++++++
 .../warning-box/warning-box.component.ts           |  30 ----
 .../shared-ui/src/lib/shared-ui.module.ts          |   6 +-
 .../streampipes/shared-ui/src/public-api.ts        |   2 +-
 .../chart-view/chart-view.component.html           |   4 +-
 .../components/chart-view/chart-view.component.ts  |  33 ++--
 .../toolbar/chart-view-toolbar.component.html      | 198 +++++++++++----------
 .../file-upload/file-upload-dialog.component.html  |   9 +-
 .../email-configuration.component.html             |  80 +++++----
 .../email-configuration.component.scss             |  25 ---
 .../email-configuration.component.ts               |   1 -
 .../export/data-export-import.component.html       |   4 +-
 .../general-configuration.component.html           |  64 ++++---
 .../general-configuration.component.scss           |   8 -
 .../edit-user-dialog.component.html                |  11 +-
 .../location-features-configuration.component.html |  40 +++--
 .../adapter-details-code.component.html            |   6 +-
 .../adapter-details-data.component.html            |   6 +-
 .../adapter-details-logs.component.html            |   4 +-
 .../adapter-details-metrics.component.html         |  10 +-
 .../pipeline-details.component.html                |   6 +-
 .../general-profile-settings.component.html        |  10 +-
 26 files changed, 425 insertions(+), 297 deletions(-)

diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.scss
 b/ui/projects/streampipes/platform-services/src/lib/model/types/alert-type.ts
similarity index 84%
rename from 
ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.scss
rename to 
ui/projects/streampipes/platform-services/src/lib/model/types/alert-type.ts
index 73ce449cf2..862508db3c 100644
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.scss
+++ 
b/ui/projects/streampipes/platform-services/src/lib/model/types/alert-type.ts
@@ -1,4 +1,4 @@
-/*!
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
@@ -16,10 +16,4 @@
  *
  */
 
-.warning {
-    border: 1px solid #dea843;
-    background: var(--color-bg-2);
-    padding: 5px;
-    margin-top: 10px;
-    margin-bottom: 10px;
-}
+export type AlertType = 'info' | 'warning' | 'error';
diff --git a/ui/projects/streampipes/platform-services/src/public-api.ts 
b/ui/projects/streampipes/platform-services/src/public-api.ts
index ea39af1a0c..2eed5bd462 100644
--- a/ui/projects/streampipes/platform-services/src/public-api.ts
+++ b/ui/projects/streampipes/platform-services/src/public-api.ts
@@ -82,6 +82,7 @@ export * from './lib/model/assets/asset.constants';
 
 export * from './lib/model/types/data-type';
 export * from './lib/model/types/semantic-type';
+export * from './lib/model/types/alert-type';
 
 export * from './lib/services/isa95-type.service';
 export * from './lib/services/live-preview.service';
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.html
 
b/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.html
similarity index 68%
rename from 
ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.html
rename to 
ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.html
index 334eb9acc3..e274752cac 100644
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.html
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.html
@@ -16,6 +16,15 @@
   ~
   -->
 
-<div fxLayout="row" fxFlex="100" class="warning">
-    <ng-content></ng-content>
+<div [ngClass]="['alert', alertClasses]" class="transition duration-300">
+    <div [ngClass]="iconContainerClasses" class="alert-icon">
+        <mat-icon>{{ displayIcon }}</mat-icon>
+    </div>
+
+    <div class="alert-content">
+        <div class="alert-title">{{ title }}</div>
+        <div class="alert-description">
+            {{ description }}
+        </div>
+    </div>
 </div>
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.scss
 
b/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.scss
new file mode 100644
index 0000000000..36bc15a7e3
--- /dev/null
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.scss
@@ -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.
+ *
+ */
+
+.alert {
+    padding: 0.75rem;
+    border-radius: 0.5rem;
+    display: flex;
+    align-items: flex-start;
+    gap: 0.75rem;
+    margin-bottom: 0.5rem;
+    margin-top: 0.5rem;
+}
+
+.alert-icon {
+    flex-shrink: 0;
+    font-weight: bold;
+    width: 1.5rem;
+    height: 1.5rem;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+}
+
+.alert-title {
+    font-weight: 700;
+    font-size: var(--font-size-sm);
+}
+
+.alert-description {
+    margin-top: 0.25rem;
+    font-size: var(--font-size-sm);
+    line-height: 1.4;
+    opacity: 0.9;
+}
+
+.alert-info {
+    background-color: #f0f7ff;
+    border-color: #3b82f6;
+    color: #1c529f;
+}
+
+.alert-icon-info {
+    color: #3b82f6;
+}
+
+.alert-warning {
+    background-color: #fff8e8;
+    border-color: #f97316;
+    color: #9a3412;
+}
+.alert-icon-warning {
+    color: #f97316;
+}
+
+.alert-error {
+    background-color: #fff5f5;
+    border-color: #ef4444;
+    color: #991b1b;
+}
+.alert-icon-error {
+    color: #ef4444;
+}
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.ts
 
b/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.ts
new file mode 100644
index 0000000000..cb9cfeaed3
--- /dev/null
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/alert-banner/alert-banner.component.ts
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+import { Component, Input } from '@angular/core';
+import { AlertType } from '@streampipes/platform-services';
+
+@Component({
+    selector: 'sp-alert-banner',
+    templateUrl: './alert-banner.component.html',
+    styleUrls: ['./alert-banner.component.scss'],
+    standalone: false,
+})
+export class SpAlertBannerComponent {
+    @Input() type: AlertType = 'info';
+    @Input() title = '';
+    @Input() description = '';
+
+    @Input() icon?: string;
+    @Input() color = '';
+
+    get alertClasses(): string {
+        if (this.color) {
+            return this.color as string;
+        }
+        return 'alert-' + this.type;
+    }
+
+    get iconContainerClasses(): string {
+        if (this.color) {
+            return '';
+        }
+        return 'alert-icon-' + this.type;
+    }
+
+    get displayIcon(): string {
+        if (this.icon) {
+            return this.icon;
+        }
+
+        switch (this.type) {
+            case 'warning':
+                return 'warning️';
+            case 'error':
+                return 'error';
+            default:
+                return 'info';
+        }
+    }
+}
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.ts
 
b/ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.ts
deleted file mode 100644
index a55b7cf6bc..0000000000
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/warning-box/warning-box.component.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-import { Component, Input } from '@angular/core';
-
-@Component({
-    selector: 'sp-warning-box',
-    templateUrl: './warning-box.component.html',
-    styleUrls: ['./warning-box.component.scss'],
-    standalone: false,
-})
-export class SpWarningBoxComponent {
-    @Input()
-    color = '';
-}
diff --git a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts 
b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
index 45e349411f..faeccbe2c1 100644
--- a/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
+++ b/ui/projects/streampipes/shared-ui/src/lib/shared-ui.module.ts
@@ -53,7 +53,6 @@ import {
 } from '@angular/material/paginator';
 import { MatSort } from '@angular/material/sort';
 import { SpExceptionDetailsComponent } from 
'./components/sp-exception-message/exception-details/exception-details.component';
-import { SpWarningBoxComponent } from 
'./components/warning-box/warning-box.component';
 import { SpBasicFieldDescriptionComponent } from 
'./components/basic-field-description/basic-field-description.component';
 import { AssetBrowserToolbarComponent } from 
'./components/asset-browser/asset-browser-toolbar/asset-browser-toolbar.component';
 import { AssetBrowserFilterComponent } from 
'./components/asset-browser/asset-browser-toolbar/asset-browser-filter/asset-browser-filter.component';
@@ -110,6 +109,7 @@ import { MatChipsModule } from '@angular/material/chips';
 import { MatAutocompleteModule } from '@angular/material/autocomplete';
 import { CdkCopyToClipboard } from '@angular/cdk/clipboard';
 import { PaginatorService } from 
'./components/sp-table/sp-paginator/sp-paginator.component';
+import { SpAlertBannerComponent } from 
'./components/alert-banner/alert-banner.component';
 
 @NgModule({
     declarations: [
@@ -140,7 +140,7 @@ import { PaginatorService } from 
'./components/sp-table/sp-paginator/sp-paginato
         SpLabelComponent,
         SpTableComponent,
         SplitSectionComponent,
-        SpWarningBoxComponent,
+        SpAlertBannerComponent,
         TimeRangeSelectorComponent,
         TimeRangeSelectorMenuComponent,
         DataExplorerRefreshIntervalSettingsComponent,
@@ -233,7 +233,7 @@ import { PaginatorService } from 
'./components/sp-table/sp-paginator/sp-paginato
         SpLabelComponent,
         SpTableComponent,
         SplitSectionComponent,
-        SpWarningBoxComponent,
+        SpAlertBannerComponent,
         CustomTimeRangeSelectionComponent,
         TimeRangeSelectorComponent,
         TimeRangeSelectorMenuComponent,
diff --git a/ui/projects/streampipes/shared-ui/src/public-api.ts 
b/ui/projects/streampipes/shared-ui/src/public-api.ts
index 5d89e09203..4268150224 100644
--- a/ui/projects/streampipes/shared-ui/src/public-api.ts
+++ b/ui/projects/streampipes/shared-ui/src/public-api.ts
@@ -45,7 +45,7 @@ export * from 
'./lib/components/sp-exception-message/exception-details/exception
 export * from './lib/components/sp-label/sp-label.component';
 export * from './lib/components/sp-table/sp-table.component';
 export * from './lib/components/sp-table/sp-table-actions.directive';
-export * from './lib/components/warning-box/warning-box.component';
+export * from './lib/components/alert-banner/alert-banner.component';
 export * from './lib/components/time-selector/time-selector.model';
 export * from './lib/components/time-selector/time-range-selector.component';
 export * from 
'./lib/components/time-selector/time-selector-menu/time-selector-menu.component';
diff --git a/ui/src/app/chart/components/chart-view/chart-view.component.html 
b/ui/src/app/chart/components/chart-view/chart-view.component.html
index 359163a764..d34c1dab33 100644
--- a/ui/src/app/chart/components/chart-view/chart-view.component.html
+++ b/ui/src/app/chart/components/chart-view/chart-view.component.html
@@ -40,9 +40,9 @@
         </div>
         <div fxFlex="100" fxLayout="column">
             @if (chartNotFound) {
-                <sp-warning-box>
+                <div class="text-xl" fxFlex="100" fxLayoutAlign="center 
center">
                     {{ 'The desired chart was not found!' | translate }}
-                </sp-warning-box>
+                </div>
             } @else {
                 <mat-drawer-container
                     class="designer-panel-container h-100 dashboard-grid"
diff --git a/ui/src/app/chart/components/chart-view/chart-view.component.ts 
b/ui/src/app/chart/components/chart-view/chart-view.component.ts
index 9675d9fdb1..b06982dbdb 100644
--- a/ui/src/app/chart/components/chart-view/chart-view.component.ts
+++ b/ui/src/app/chart/components/chart-view/chart-view.component.ts
@@ -188,23 +188,25 @@ export class ChartViewComponent
                 if (!res) {
                     this.dataViewLoaded = true;
                     return;
-                }
-                this.dataView = res;
-                this.originalDataView = JSON.parse(
-                    JSON.stringify(this.dataView),
-                );
-                if (!this.dataView.timeSettings?.startTime) {
-                    this.timeSettings = this.makeDefaultTimeSettings();
                 } else {
-                    this.timeSelectionService.updateTimeSettings(
-                        this.timeSelectionService.defaultQuickTimeSelections,
-                        this.dataView.timeSettings as TimeSettings,
-                        new Date(),
+                    this.dataView = res;
+                    this.originalDataView = JSON.parse(
+                        JSON.stringify(this.dataView),
                     );
-                    this.timeSettings = this.dataView
-                        .timeSettings as TimeSettings;
+                    if (!this.dataView.timeSettings?.startTime) {
+                        this.timeSettings = this.makeDefaultTimeSettings();
+                    } else {
+                        this.timeSelectionService.updateTimeSettings(
+                            this.timeSelectionService
+                                .defaultQuickTimeSelections,
+                            this.dataView.timeSettings as TimeSettings,
+                            new Date(),
+                        );
+                        this.timeSettings = this.dataView
+                            .timeSettings as TimeSettings;
+                    }
+                    this.afterDataViewLoaded();
                 }
-                this.afterDataViewLoaded();
             });
     }
 
@@ -228,6 +230,9 @@ export class ChartViewComponent
 
     setShouldShowConfirm(): boolean {
         let originalTimeSettings: TimeSettings;
+        if (!this.dataView) {
+            return false;
+        }
         if (this.originalDataView?.timeSettings) {
             originalTimeSettings = this.originalDataView
                 .timeSettings as TimeSettings;
diff --git 
a/ui/src/app/chart/components/chart-view/toolbar/chart-view-toolbar.component.html
 
b/ui/src/app/chart/components/chart-view/toolbar/chart-view-toolbar.component.html
index c7d1eefbff..e1f8ed9298 100644
--- 
a/ui/src/app/chart/components/chart-view/toolbar/chart-view-toolbar.component.html
+++ 
b/ui/src/app/chart/components/chart-view/toolbar/chart-view-toolbar.component.html
@@ -17,111 +17,113 @@
 -->
 
 <div fxLayout="row" fxFlex="100">
-    <div
-        class="data-explorer-options-item"
-        fxLayoutAlign="start center"
-        fxLayout="row"
-        fxLayoutGap="10px"
-        fxFlex="100"
-    >
+    @if (configuredWidget) {
         <div
-            fxFlex="25"
-            fxLayout="row"
+            class="data-explorer-options-item"
             fxLayoutAlign="start center"
-            class="widget-header-text mr-15"
+            fxLayout="row"
+            fxLayoutGap="10px"
+            fxFlex="100"
         >
-            @if (editMode) {
-                <div
-                    fxFlex="100"
-                    fxLayout="row"
-                    fxLayoutAlign="start center"
-                    class="form-field-small widget-title-container"
-                >
-                    <span class="widget-title-text">{{
-                        'Chart Name' | translate
-                    }}</span>
-                    <mat-form-field
-                        appearance="outline"
-                        color="accent"
+            <div
+                fxFlex="25"
+                fxLayout="row"
+                fxLayoutAlign="start center"
+                class="widget-header-text mr-15"
+            >
+                @if (editMode) {
+                    <div
                         fxFlex="100"
-                        subscriptSizing="dynamic"
+                        fxLayout="row"
+                        fxLayoutAlign="start center"
+                        class="form-field-small widget-title-container"
                     >
-                        <input
-                            data-cy="appearance-config-widget-title"
-                            matInput
-                            [(ngModel)]="
-                                configuredWidget.baseAppearanceConfig
-                                    .widgetTitle
-                            "
-                        />
-                    </mat-form-field>
-                </div>
-            }
-        </div>
+                        <span class="widget-title-text">{{
+                            'Chart Name' | translate
+                        }}</span>
+                        <mat-form-field
+                            appearance="outline"
+                            color="accent"
+                            fxFlex="100"
+                            subscriptSizing="dynamic"
+                        >
+                            <input
+                                data-cy="appearance-config-widget-title"
+                                matInput
+                                [(ngModel)]="
+                                    configuredWidget.baseAppearanceConfig
+                                        .widgetTitle
+                                "
+                            />
+                        </mat-form-field>
+                    </div>
+                }
+            </div>
 
-        @if (editMode) {
-            <button
-                mat-flat-button
-                [matTooltip]="'Save' | translate"
-                class="edit-menu-btn"
-                (click)="saveDataViewEmitter.emit()"
-                data-cy="save-data-view-btn"
-            >
-                <mat-icon>save</mat-icon>
-                {{ 'Save' | translate }}
-            </button>
-        }
-        @if (isAssetAdmin) {
-            <button
-                mat-flat-button
-                [matTooltip]="'Add to Asset' | translate"
-                class="mat-basic"
-                (click)="addToAssetEmitter.emit()"
-                data-cy="add-to-Asset-data-view-btn"
-            >
-                <mat-icon>precision_manufacturing</mat-icon>
-                {{ 'Add To Asset' | translate }}
-            </button>
-        }
-        @if (editMode) {
-            <button
-                mat-flat-button
-                [matTooltip]="'Discard' | translate"
-                class="mat-basic mr-10 edit-menu-btn"
-                (click)="discardDataViewEmitter.emit()"
-                data-cy="discard-data-explorer-widget-btn"
-            >
-                <i class="material-icons">undo</i>
-                <span>&nbsp;{{ 'Discard' | translate }}</span>
-            </button>
-        }
-        @if (editMode) {
-            <button
-                mat-icon-button
-                color="accent"
-                [matTooltip]="'Download data' | translate"
-                (click)="downloadFileEmitter.emit()"
-                data-cy="data-view-data-download-btn"
-            >
-                <mat-icon>get_app</mat-icon>
-            </button>
-        }
-
-        <span fxFlex></span>
-        <div
-            class="data-explorer-options-item"
-            style="margin-right: 0"
-            fxLayoutAlign="end center"
-            fxFlex
-            fxLayout="row"
-        >
-            @if (editMode || timeRangeVisible) {
-                <sp-time-range-selector
-                    (dateRangeEmitter)="updateDateRangeEmitter.emit($event)"
-                    [timeSettings]="timeSettings"
+            @if (editMode) {
+                <button
+                    mat-flat-button
+                    [matTooltip]="'Save' | translate"
+                    class="edit-menu-btn"
+                    (click)="saveDataViewEmitter.emit()"
+                    data-cy="save-data-view-btn"
+                >
+                    <mat-icon>save</mat-icon>
+                    {{ 'Save' | translate }}
+                </button>
+            }
+            @if (isAssetAdmin) {
+                <button
+                    mat-flat-button
+                    [matTooltip]="'Add to Asset' | translate"
+                    class="mat-basic"
+                    (click)="addToAssetEmitter.emit()"
+                    data-cy="add-to-Asset-data-view-btn"
+                >
+                    <mat-icon>precision_manufacturing</mat-icon>
+                    {{ 'Add To Asset' | translate }}
+                </button>
+            }
+            @if (editMode) {
+                <button
+                    mat-flat-button
+                    [matTooltip]="'Discard' | translate"
+                    class="mat-basic mr-10 edit-menu-btn"
+                    (click)="discardDataViewEmitter.emit()"
+                    data-cy="discard-data-explorer-widget-btn"
+                >
+                    <i class="material-icons">undo</i>
+                    <span>&nbsp;{{ 'Discard' | translate }}</span>
+                </button>
+            }
+            @if (editMode) {
+                <button
+                    mat-icon-button
+                    color="accent"
+                    [matTooltip]="'Download data' | translate"
+                    (click)="downloadFileEmitter.emit()"
+                    data-cy="data-view-data-download-btn"
                 >
-                </sp-time-range-selector>
+                    <mat-icon>get_app</mat-icon>
+                </button>
             }
+
+            <span fxFlex></span>
+            <div
+                class="data-explorer-options-item"
+                style="margin-right: 0"
+                fxLayoutAlign="end center"
+                fxFlex
+                fxLayout="row"
+            >
+                @if (editMode || timeRangeVisible) {
+                    <sp-time-range-selector
+                        
(dateRangeEmitter)="updateDateRangeEmitter.emit($event)"
+                        [timeSettings]="timeSettings"
+                    >
+                    </sp-time-range-selector>
+                }
+            </div>
         </div>
-    </div>
+    }
 </div>
diff --git 
a/ui/src/app/configuration/dialog/file-upload/file-upload-dialog.component.html 
b/ui/src/app/configuration/dialog/file-upload/file-upload-dialog.component.html
index 3e180822b3..ab0dee6b8b 100644
--- 
a/ui/src/app/configuration/dialog/file-upload/file-upload-dialog.component.html
+++ 
b/ui/src/app/configuration/dialog/file-upload/file-upload-dialog.component.html
@@ -19,9 +19,12 @@
 <div class="sp-dialog-container">
     <div class="sp-dialog-content p-15" fxLayout="column">
         @if (uploadError) {
-            <sp-warning-box class="text-sm">
-                {{ uploadErrorMessage }}
-            </sp-warning-box>
+            <sp-alert-banner
+                type="error"
+                title="'Could not upload file' | translate "
+                [description]="uploadErrorMessage"
+            >
+            </sp-alert-banner>
         }
         @if (this.duplicateFileNames.length === 0) {
             <div fxFlex="100">
diff --git 
a/ui/src/app/configuration/email-configuration/email-configuration.component.html
 
b/ui/src/app/configuration/email-configuration/email-configuration.component.html
index 9255bb8b4e..4ff4605ac3 100644
--- 
a/ui/src/app/configuration/email-configuration/email-configuration.component.html
+++ 
b/ui/src/app/configuration/email-configuration/email-configuration.component.html
@@ -31,9 +31,11 @@
                         fxFlex="100"
                         fxLayout="column"
                     >
-                        <div class="subsection-title">
-                            {{ 'Mail Server' | translate }}
-                        </div>
+                        <sp-basic-header-title-component
+                            [compact]="true"
+                            [title]="'Mail Server' | translate"
+                        >
+                        </sp-basic-header-title-component>
                         <mat-form-field color="accent">
                             <mat-label>SMTP Host</mat-label>
                             <input
@@ -53,9 +55,11 @@
                                 required
                             />
                         </mat-form-field>
-                        <div class="subsection-title">
-                            {{ 'Transport' | translate }}
-                        </div>
+                        <sp-basic-header-title-component
+                            [compact]="true"
+                            [title]="'Transport' | translate"
+                        >
+                        </sp-basic-header-title-component>
                         <mat-radio-group
                             fxLayout="column"
                             formControlName="transport"
@@ -70,9 +74,11 @@
                                 >TLS</mat-radio-button
                             >
                         </mat-radio-group>
-                        <div class="subsection-title mt-20">
-                            {{ 'Authentication' | translate }}
-                        </div>
+                        <sp-basic-header-title-component
+                            [compact]="true"
+                            [title]="'Authentication' | translate"
+                        >
+                        </sp-basic-header-title-component>
                         <mat-checkbox formControlName="usesAuthentication"
                             >{{
                                 'SMTP server requires authentication'
@@ -104,9 +110,11 @@
                                 />
                             </mat-form-field>
                         }
-                        <div class="subsection-title mt-20">
-                            {{ 'Proxy' | translate }}
-                        </div>
+                        <sp-basic-header-title-component
+                            [compact]="true"
+                            [title]="'Proxy' | translate"
+                        >
+                        </sp-basic-header-title-component>
                         <mat-checkbox formControlName="usesProxy">{{
                             'Uses proxy' | translate
                         }}</mat-checkbox>
@@ -172,9 +180,11 @@
                                 />
                             </mat-form-field>
                         }
-                        <div class="subsection-title mt-20">
-                            {{ 'Sender' | translate }}
-                        </div>
+                        <sp-basic-header-title-component
+                            [compact]="true"
+                            [title]="'Sender' | translate"
+                        >
+                        </sp-basic-header-title-component>
                         <mat-form-field color="accent">
                             <mat-label>{{
                                 'Sender Email Address' | translate
@@ -254,31 +264,31 @@
                                         !sendingTestMailInProgress &&
                                         sendingTestMailSuccess
                                     ) {
-                                        <h5>
-                                            {{
-                                                'Success - please check your 
mail inbox.'
-                                                    | translate
-                                            }}
-                                        </h5>
+                                        <sp-alert-banner
+                                            type="info"
+                                            [title]="
+                                                'Success - please check your 
mail inbox. | translate'
+                                            "
+                                        >
+                                        </sp-alert-banner>
                                     }
                                     @if (
                                         !sendingTestMailInProgress &&
                                         !sendingTestMailSuccess
                                     ) {
-                                        <div fxLayout="column">
-                                            <div class="error-panel">
-                                                <h4>
-                                                    {{
-                                                        'Could not send email'
-                                                            | translate
-                                                    }}
-                                                </h4>
-                                                <h5>
-                                                    {{
-                                                        
sendingEmailErrorMessage
-                                                    }}
-                                                </h5>
-                                            </div>
+                                        <div fxLayout="row" fxFlex="100">
+                                            <sp-alert-banner
+                                                class="w-100"
+                                                type="error"
+                                                [title]="
+                                                    'Could not send email'
+                                                        | translate
+                                                "
+                                                [description]="
+                                                    sendingEmailErrorMessage
+                                                "
+                                            >
+                                            </sp-alert-banner>
                                         </div>
                                     }
                                 </div>
diff --git 
a/ui/src/app/configuration/email-configuration/email-configuration.component.scss
 
b/ui/src/app/configuration/email-configuration/email-configuration.component.scss
deleted file mode 100644
index 1026aeaae1..0000000000
--- 
a/ui/src/app/configuration/email-configuration/email-configuration.component.scss
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-.error-panel {
-    margin-top: 10px;
-    padding: 10px;
-    border: 1px solid var(--color-warn);
-    background: var(--color-bg-1);
-    border-radius: 5px;
-}
diff --git 
a/ui/src/app/configuration/email-configuration/email-configuration.component.ts 
b/ui/src/app/configuration/email-configuration/email-configuration.component.ts
index c68d08c1ab..ceeb26dc49 100644
--- 
a/ui/src/app/configuration/email-configuration/email-configuration.component.ts
+++ 
b/ui/src/app/configuration/email-configuration/email-configuration.component.ts
@@ -32,7 +32,6 @@ import { TranslateService } from '@ngx-translate/core';
 @Component({
     selector: 'sp-email-configuration',
     templateUrl: './email-configuration.component.html',
-    styleUrls: ['./email-configuration.component.scss'],
     standalone: false,
 })
 export class EmailConfigurationComponent implements OnInit {
diff --git a/ui/src/app/configuration/export/data-export-import.component.html 
b/ui/src/app/configuration/export/data-export-import.component.html
index 40e30aef9e..2175486f27 100644
--- a/ui/src/app/configuration/export/data-export-import.component.html
+++ b/ui/src/app/configuration/export/data-export-import.component.html
@@ -31,7 +31,9 @@
                             (change)="
                                 handleSelectionChange($event, asset.elementId)
                             "
-                            ><h4>{{ asset.assetName }}</h4></mat-checkbox
+                            ><span class="text-md">{{
+                                asset.assetName
+                            }}</span></mat-checkbox
                         >
                     </div>
                 }
diff --git 
a/ui/src/app/configuration/general-configuration/general-configuration.component.html
 
b/ui/src/app/configuration/general-configuration/general-configuration.component.html
index b5c60d3e24..8ff7e33252 100644
--- 
a/ui/src/app/configuration/general-configuration/general-configuration.component.html
+++ 
b/ui/src/app/configuration/general-configuration/general-configuration.component.html
@@ -30,21 +30,26 @@
                         [subtitle]="'Basic settings' | translate"
                     >
                         @if (!generalConfig.configured) {
-                            <div class="warning mb-10">
-                                {{
+                            <sp-alert-banner
+                                type="info"
+                                [title]="'Default values' | translate"
+                                [description]="
                                     'These are default values - to use 
features such as email you need to store these values once.'
                                         | translate
-                                }}
-                            </div>
+                                "
+                            >
+                            </sp-alert-banner>
                         }
-                        <div
-                            fxLayout="row"
-                            fxLayoutAlign="start center"
-                            fxLayoutGap="10px"
-                        >
-                            <div class="subsection-title">
-                                {{ 'App Name' | translate }}
-                            </div>
+                        <div fxLayout="column">
+                            <sp-basic-header-title-component
+                                [compact]="true"
+                                [title]="'App Name' | translate"
+                                [description]="
+                                    'The app name as shown on the login screen 
and in emails'
+                                        | translate
+                                "
+                            >
+                            </sp-basic-header-title-component>
                             <mat-form-field appearance="outline" fxFlex>
                                 <input
                                     formControlName="appName"
@@ -55,14 +60,16 @@
                                 />
                             </mat-form-field>
                         </div>
-                        <div
-                            fxLayout="row"
-                            fxLayoutAlign="start center"
-                            fxLayoutGap="10px"
-                        >
-                            <div class="subsection-title">
-                                {{ 'Host and Port' | translate }}
-                            </div>
+                        <div fxLayout="column">
+                            <sp-basic-header-title-component
+                                [compact]="true"
+                                [title]="'Host and Port' | translate"
+                                [description]="
+                                    'The URL where the application can be 
accessed, e.g., for links in emails.'
+                                        | translate
+                                "
+                            >
+                            </sp-basic-header-title-component>
                             <div fxLayout="column" fxFlex="100">
                                 <div fxLayout="row">
                                     <div
@@ -129,12 +136,15 @@
                             !generalConfig.configured ||
                             !mailConfig.emailConfigured
                         ) {
-                            <div class="warning mb-10">
-                                {{
-                                    'Self - registration requires valid mail 
server and basic host settings.'
+                            <sp-alert-banner
+                                type="info"
+                                [title]="'Configuration required' | translate"
+                                [description]="
+                                    'Self-registration requires valid mail 
server and configured basic host/port settings.'
                                         | translate
-                                }}
-                            </div>
+                                "
+                            >
+                            </sp-alert-banner>
                         }
                         @if (
                             generalConfig.configured &&
@@ -199,8 +209,8 @@
                             [disabled]="parentForm.invalid"
                             data-cy="sp-element-general-config-save"
                         >
-                            <i class="material-icons">save</i
-                            ><span>&nbsp;{{ 'Save' | translate }}</span>
+                            <mat-icon>save</mat-icon>
+                            <span>{{ 'Save' | translate }}</span>
                         </button>
                     </div>
                 </form>
diff --git 
a/ui/src/app/configuration/general-configuration/general-configuration.component.scss
 
b/ui/src/app/configuration/general-configuration/general-configuration.component.scss
index 8283390e12..efc38fc2b0 100644
--- 
a/ui/src/app/configuration/general-configuration/general-configuration.component.scss
+++ 
b/ui/src/app/configuration/general-configuration/general-configuration.component.scss
@@ -19,11 +19,3 @@
 .ml-10 {
     margin-left: 10px;
 }
-
-.warning {
-    border: 1px solid var(--mat-sys-error);
-    background: var(--mat-sys-error-container);
-    color: var(--mat-sys-on-error-container);
-    padding: 5px;
-    font-size: var(--font-size-sm);
-}
diff --git 
a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
 
b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
index 3ffd55cc6e..3ad71a32e3 100644
--- 
a/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
+++ 
b/ui/src/app/configuration/security-configuration/edit-user-dialog/edit-user-dialog.component.html
@@ -21,12 +21,15 @@
         <div class="sp-dialog-content">
             <div fxFlex="100" fxLayout="column" class="p-15">
                 @if (isUserAccount && isExternalProvider) {
-                    <sp-warning-box>
-                        {{
+                    <sp-alert-banner
+                        class="w-100"
+                        type="info"
+                        [title]="
                             'Settings of externally-managed users cannot be 
changed.'
                                 | translate
-                        }}
-                    </sp-warning-box>
+                        "
+                    >
+                    </sp-alert-banner>
                 }
                 <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
                     <div class="general-options-panel" fxLayout="column">
diff --git 
a/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html
 
b/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html
index b8c61d46a7..9b3340bb8c 100644
--- 
a/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html
+++ 
b/ui/src/app/configuration/sites-configuration/location-features-configuration/location-features-configuration.component.html
@@ -32,9 +32,15 @@
                 </mat-checkbox>
                 @if (showLocationDetails) {
                     <div class="mt-10">
-                        <div class="subsection-title">
-                            {{ 'Layer type' | translate }}
-                        </div>
+                        <sp-basic-header-title-component
+                            [compact]="true"
+                            [title]="'Layer type' | translate"
+                            [description]="
+                                'Both tile servers and vector styles are 
supported.'
+                                    | translate
+                            "
+                        >
+                        </sp-basic-header-title-component>
                         <mat-radio-group
                             formControlName="mapLayerType"
                             fxLayout="row"
@@ -53,12 +59,16 @@
                                 {{ 'Vector' | translate }}
                             </mat-radio-button>
                         </mat-radio-group>
-                        <div class="subsection-title mt-10">
-                            {{
-                                'Style/Tile server URL (for tile server, use 
placeholders for x, y and z coordinates)'
+                        <sp-basic-header-title-component
+                            class="mt-10"
+                            [compact]="true"
+                            [title]="'Style/Tile server URL' | translate"
+                            [description]="
+                                'For tile server, use placeholders for x, y 
and z coordinates'
                                     | translate
-                            }}
-                        </div>
+                            "
+                        >
+                        </sp-basic-header-title-component>
                         <mat-form-field
                             color="accent"
                             class="w-100"
@@ -71,12 +81,16 @@
                                 data-cy="sites-location-config-tile-server"
                             />
                         </mat-form-field>
-                        <div class="subsection-title mt-10">
-                            {{
-                                'Copyright notice if required by the tile 
server'
+                        <sp-basic-header-title-component
+                            class="mt-10"
+                            [compact]="true"
+                            [title]="'Copyright notice' | translate"
+                            [description]="
+                                'Will be shown on the map if required by the 
tile server'
                                     | translate
-                            }}
-                        </div>
+                            "
+                        >
+                        </sp-basic-header-title-component>
                         <mat-form-field
                             color="accent"
                             class="w-100"
diff --git 
a/ui/src/app/connect/components/adapter-details/adapter-details-code/adapter-details-code.component.html
 
b/ui/src/app/connect/components/adapter-details/adapter-details-code/adapter-details-code.component.html
index c433c0f408..bbd0a4b257 100644
--- 
a/ui/src/app/connect/components/adapter-details/adapter-details-code/adapter-details-code.component.html
+++ 
b/ui/src/app/connect/components/adapter-details/adapter-details-code/adapter-details-code.component.html
@@ -22,11 +22,11 @@
     [showBackLink]="true"
     [backLinkTarget]="['connect']"
 >
-    <div fxLayout="column">
+    <div fxLayout="column" fxFlex="100">
         @if (adapterNotFound) {
-            <sp-warning-box>
+            <div class="text-xl" fxFlex="100" fxLayoutAlign="center center">
                 {{ 'The desired adapter was not found!' | translate }}
-            </sp-warning-box>
+            </div>
         } @else {
             @if (adapter) {
                 <div fxLayout="column">
diff --git 
a/ui/src/app/connect/components/adapter-details/adapter-details-data/adapter-details-data.component.html
 
b/ui/src/app/connect/components/adapter-details/adapter-details-data/adapter-details-data.component.html
index e07a86e9b0..44981af63c 100644
--- 
a/ui/src/app/connect/components/adapter-details/adapter-details-data/adapter-details-data.component.html
+++ 
b/ui/src/app/connect/components/adapter-details/adapter-details-data/adapter-details-data.component.html
@@ -22,11 +22,11 @@
     [showBackLink]="true"
     [backLinkTarget]="['connect']"
 >
-    <div fxLayout="column">
+    <div fxLayout="column" fxFlex="100">
         @if (adapterNotFound) {
-            <sp-warning-box>
+            <div class="text-xl" fxFlex="100" fxLayoutAlign="center center">
                 {{ 'The desired adapter was not found!' | translate }}
-            </sp-warning-box>
+            </div>
         } @else {
             @if (adapter) {
                 <div fxLayout="row">
diff --git 
a/ui/src/app/connect/components/adapter-details/adapter-details-logs/adapter-details-logs.component.html
 
b/ui/src/app/connect/components/adapter-details/adapter-details-logs/adapter-details-logs.component.html
index 57afa84365..48857ba0fa 100644
--- 
a/ui/src/app/connect/components/adapter-details/adapter-details-logs/adapter-details-logs.component.html
+++ 
b/ui/src/app/connect/components/adapter-details/adapter-details-logs/adapter-details-logs.component.html
@@ -34,9 +34,9 @@
         </button>
     </div>
     @if (adapterNotFound) {
-        <sp-warning-box>
+        <div class="text-xl" fxFlex="100" fxLayoutAlign="center center">
             {{ 'The desired adapter was not found!' | translate }}
-        </sp-warning-box>
+        </div>
     } @else {
         @if (adapter) {
             <div fxFlex="100" fxLayout="column">
diff --git 
a/ui/src/app/connect/components/adapter-details/adapter-details-metrics/adapter-details-metrics.component.html
 
b/ui/src/app/connect/components/adapter-details/adapter-details-metrics/adapter-details-metrics.component.html
index 2eb55a476c..b5a4a32280 100644
--- 
a/ui/src/app/connect/components/adapter-details/adapter-details-metrics/adapter-details-metrics.component.html
+++ 
b/ui/src/app/connect/components/adapter-details/adapter-details-metrics/adapter-details-metrics.component.html
@@ -22,7 +22,7 @@
     [showBackLink]="true"
     [backLinkTarget]="['connect']"
 >
-    <div nav fxFlex="100" fxLayout="row" fxLayoutAlign="end center">
+    <div nav fxLayout="row" fxLayoutAlign="end center">
         <button
             mat-icon-button
             color="accent"
@@ -34,11 +34,9 @@
         </button>
     </div>
     @if (adapterNotFound) {
-        <sp-warning-box>
-            {{
-                'The desired adapter was not found!' | translate
-            }}</sp-warning-box
-        >
+        <div class="text-xl" fxFlex="100" fxLayoutAlign="center center">
+            {{ 'The desired adapter was not found!' | translate }}
+        </div>
     } @else {
         @if (adapter && adapterMetrics) {
             <div fxFlex="100" fxLayout="column">
diff --git a/ui/src/app/pipeline-details/pipeline-details.component.html 
b/ui/src/app/pipeline-details/pipeline-details.component.html
index 1d775f9182..22e1c7ec5c 100644
--- a/ui/src/app/pipeline-details/pipeline-details.component.html
+++ b/ui/src/app/pipeline-details/pipeline-details.component.html
@@ -36,10 +36,8 @@
     </div>
     <div fxFlex="100" fxLayout="column">
         @if (pipelineNotFound) {
-            <div>
-                <sp-warning-box color="primary">{{
-                    'The desired pipeline was not found!' | translate
-                }}</sp-warning-box>
+            <div class="text-xl" fxFlex="100" fxLayoutAlign="center center">
+                {{ 'The desired pipeline was not found!' | translate }}
             </div>
         }
 
diff --git 
a/ui/src/app/profile/components/general/general-profile-settings.component.html 
b/ui/src/app/profile/components/general/general-profile-settings.component.html
index 0ae9910f87..7effd6d0a4 100644
--- 
a/ui/src/app/profile/components/general/general-profile-settings.component.html
+++ 
b/ui/src/app/profile/components/general/general-profile-settings.component.html
@@ -26,12 +26,14 @@
                 "
             >
                 @if (isExternalUser) {
-                    <sp-warning-box>
-                        {{
+                    <sp-alert-banner
+                        type="info"
+                        [title]="
                             'Settings for externally-managed users cannot be 
changed'
                                 | translate
-                        }}
-                    </sp-warning-box>
+                        "
+                    >
+                    </sp-alert-banner>
                 }
                 <div fxLayout="row" fxLayoutAlign="start center">
                     <span>{{ userData.username }}</span>

Reply via email to