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

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

commit 70edd5aa22bcee1bbdefca25ed8c27530db5f59f
Author: Dominik Riemer <[email protected]>
AuthorDate: Thu Nov 13 13:08:44 2025 +0100

    feat: Harmonize layout in configuration view, add pagination to tables
---
 .../components/sp-table/sp-table.component.html    |   5 +-
 .../lib/components/sp-table/sp-table.component.ts  |   2 +-
 .../split-section/split-section.component.html     |  26 +-
 .../split-section/split-section.component.scss     |  85 ++++-
 .../split-section/split-section.component.ts       |   3 +
 .../datalake-configuration.component.html          | 347 +++++++++------------
 .../export/data-export-import.component.html       |  13 +-
 .../app/configuration/files/files.component.html   |   8 +-
 .../general-configuration.component.html           | 169 +++++-----
 .../link-settings/link-settings.component.html     |  13 +-
 .../label-configuration.component.html             |  12 +-
 .../messaging-configuration.component.html         |  23 +-
 .../abstract-security-principal-config.ts          |   2 +-
 .../role-configuration.component.html              |  17 +-
 .../security-configuration.component.html          |  52 ++-
 .../security-configuration.component.ts            |  37 ++-
 .../security-service-config.component.html         |  16 +-
 .../security-user-config.component.html            |  10 +-
 .../user-group-configuration.component.html        |  16 +-
 .../location-features-configuration.component.html |  49 ++-
 .../site-area-configuration.component.html         |  22 +-
 ui/src/scss/sp/main.scss                           |   4 +-
 22 files changed, 489 insertions(+), 442 deletions(-)

diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.html
 
b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.html
index 045643415b..fc63ce414b 100644
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.html
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.html
@@ -81,8 +81,9 @@
     <div fxFlex="100" fxLayoutAlign="end end" class="paginator-container">
         <mat-paginator
             #paginator
-            [pageSize]="20"
-            [hidePageSize]="true"
+            [pageSize]="pageSize"
+            [pageSizeOptions]="[5, 10, 20, 50]"
+            [hidePageSize]="false"
             [showFirstLastButtons]="true"
         ></mat-paginator>
     </div>
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.ts
 
b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.ts
index 42fa5d2d4f..4a749d30b9 100644
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.ts
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/sp-table/sp-table.component.ts
@@ -67,7 +67,7 @@ export class SpTableComponent<T> implements AfterViewInit, 
AfterContentInit {
     @ContentChild(SpTableActionsDirective, { read: TemplateRef })
     actionsTemplate?: TemplateRef<any>;
 
-    pageSize = 1;
+    pageSize = 10;
     timedOutCloser: any;
     trigger: MatMenuTrigger | undefined = undefined;
 
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.html
 
b/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.html
index 751f19934b..faab80916a 100644
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.html
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.html
@@ -16,14 +16,22 @@
   ~
   -->
 
-<div fxFlex="100" fxLayout="column">
-    <div fxLayout="row">
-        <div fxFlex="210px" fxLayout="column" class="split-section">
-            <div class="split-section-title">{{ title }}</div>
-            <div class="split-section-description">{{ subtitle }}</div>
-        </div>
-        <div fxFlex fxLayout="column">
-            <ng-content></ng-content>
+<section class="section" [class.compact]="compact">
+    <header class="section-header">
+        <div class="eyebrow" *ngIf="eyebrow">{{ eyebrow }}</div>
+
+        <h2 class="title">{{ title }}</h2>
+
+        <div class="header-actions">
+            <ng-content select="[section-actions]"></ng-content>
         </div>
+
+        <p class="description" *ngIf="subtitle">
+            {{ subtitle }}
+        </p>
+    </header>
+
+    <div class="section-body" role="group" fxLayout="column">
+        <ng-content></ng-content>
     </div>
-</div>
+</section>
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.scss
 
b/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.scss
index 5a1420cf05..c7820057d2 100644
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.scss
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.scss
@@ -17,22 +17,85 @@
  */
 
 :host {
-    margin-top: 20px;
     width: 100%;
-    margin-bottom: 20px;
+    display: block;
+    --accent: hsl(221 83% 53%);
+    --fg-muted: color-mix(in oklab, currentColor 60%, transparent);
+    --divider: color-mix(in oklab, currentColor 18%, transparent);
 }
 
-.split-section-title {
-    font-weight: bold;
-    font-size: 16pt;
+.section {
+    position: relative;
+    padding: 0.75rem 0 1rem 0.875rem;
 }
 
-.split-section-description {
-    font-size: 12pt;
+.section::before {
+    content: '';
+    position: absolute;
+    left: 0;
+    top: 0.75rem;
+    bottom: 1rem;
+    width: 2px;
+    background: var(--color-primary);
+    border-radius: 2px;
+    opacity: 0.35;
 }
 
-.split-section {
-    border-right: 1px solid var(--color-bg-3);
-    margin-right: 15px;
-    padding-right: 5px;
+.section-header {
+    display: grid;
+    grid-template-columns: 1fr auto;
+    grid-template-rows: auto auto;
+    column-gap: 0.75rem;
+    row-gap: 0.25rem;
+    align-items: start;
+}
+
+.eyebrow {
+    grid-column: 1 / -1;
+    text-transform: uppercase;
+    letter-spacing: 0.06em;
+    font-size: 0.75rem;
+    line-height: 1.2;
+    color: var(--fg-muted);
+}
+
+.title {
+    margin: 0;
+    font-weight: 600;
+    line-height: 1.2;
+    font-size: clamp(1rem, 1.8vw, 1.25rem);
+    letter-spacing: -0.01em;
+}
+
+.header-actions {
+    grid-column: 2 / 3;
+    grid-row: 1 / 3;
+    display: flex;
+    gap: 0.5rem;
+    align-items: center;
+}
+
+.description {
+    grid-column: 1 / 2;
+    grid-row: 2 / 3;
+    margin: 0;
+    font-size: clamp(0.875rem, 1.2vw, 0.95rem);
+    line-height: 1.35;
+    color: var(--fg-muted);
+    font-weight: 300;
+}
+
+.section-body {
+    margin-top: 0.75rem;
+    margin-left: 20px;
+    display: block;
+}
+
+.section.compact {
+    padding-top: 0.5rem;
+    padding-bottom: 0.75rem;
+}
+
+.section.compact .description {
+    font-size: 0.875rem;
 }
diff --git 
a/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.ts
 
b/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.ts
index a03aeb3e27..7c43dfcb89 100644
--- 
a/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.ts
+++ 
b/ui/projects/streampipes/shared-ui/src/lib/components/split-section/split-section.component.ts
@@ -30,4 +30,7 @@ export class SplitSectionComponent {
 
     @Input()
     subtitle: string;
+
+    @Input() eyebrow = '';
+    @Input() compact = false;
 }
diff --git 
a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
 
b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
index 60c557f1ee..a78bea7e96 100644
--- 
a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
+++ 
b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
@@ -23,27 +23,17 @@
                 [title]="'Data Lake Settings' | translate"
                 [subtitle]="'Manage persisted data streams' | translate"
             >
+                <button
+                    section-actions
+                    color="accent"
+                    mat-icon-button
+                    [matTooltip]="'Refresh' | translate"
+                    data-cy="refresh-data-lake-measures"
+                    (click)="loadAvailableMeasurements()"
+                >
+                    <mat-icon>refresh</mat-icon>
+                </button>
                 <div fxFlex="100" fxLayout="column">
-                    <div fxFlex="100" fxLayout="row">
-                        <div
-                            fxFlex
-                            fxLayoutAlign="start center"
-                            class="subsection-title"
-                        >
-                            {{ 'Existing data lake indices' | translate }}
-                        </div>
-                        <div fxLayout="row" fxLayoutAlign="end center">
-                            <button
-                                color="accent"
-                                mat-icon-button
-                                [matTooltip]="'Refresh' | translate"
-                                data-cy="refresh-data-lake-measures"
-                                (click)="loadAvailableMeasurements()"
-                            >
-                                <mat-icon>refresh</mat-icon>
-                            </button>
-                        </div>
-                    </div>
                     <table
                         fxFlex="100"
                         mat-table
@@ -61,9 +51,7 @@
                                 {{ 'Name' | translate }}
                             </th>
                             <td mat-cell *matCellDef="let configurationEntry">
-                                <h4 style="margin-bottom: 0px">
-                                    {{ configurationEntry.name }}
-                                </h4>
+                                {{ configurationEntry.name }}
                             </td>
                         </ng-container>
 
@@ -286,191 +274,154 @@
                         | translate
                 "
             >
-                <div fxFlex="100" fxLayout="column">
-                    <div fxFlex="100" fxLayout="row">
-                        <div
-                            fxFlex
-                            fxLayoutAlign="start center"
-                            class="subsection-title"
-                        >
-                            {{ 'Existing Export Providers' | translate }}
-                        </div>
-
-                        <div fxLayout="row" fxLayoutAlign="end center">
-                            <button
-                                color="accent"
-                                mat-icon-button
-                                matTooltip="{{
-                                    'New Export Provider' | translate
-                                }}"
-                                data-cy="new-export-providers"
-                                (click)="createExportProvider(null)"
-                            >
-                                <mat-icon>add</mat-icon>
-                            </button>
-                        </div>
-
-                        <div fxLayout="row" fxLayoutAlign="end center">
-                            <button
-                                color="accent"
-                                mat-icon-button
-                                matTooltip="{{ 'Refresh' | translate }}"
-                                data-cy="refresh-export-providers-measures"
-                                (click)="loadAvailableExportProvider()"
-                            >
-                                <mat-icon>refresh</mat-icon>
-                            </button>
-                        </div>
-                    </div>
-
-                    <table
-                        fxFlex="100"
-                        mat-table
-                        data-cy="exportproviders-settings"
-                        [dataSource]="dataSourceExport"
-                        style="width: 100%"
-                        matSort
+                <div
+                    fxLayout="row"
+                    fxLayoutAlign="end center"
+                    section-actions
+                    fxLayoutGap="5px"
+                >
+                    <button
+                        mat-flat-button
+                        matTooltip="{{ 'New' | translate }}"
+                        data-cy="new-export-providers"
+                        (click)="createExportProvider(null)"
                     >
-                        <ng-container matColumnDef="providertype">
-                            <th
-                                mat-header-cell
-                                mat-sort-header
-                                *matHeaderCellDef
-                            >
-                                {{ 'Provider Type' | translate }}
-                            </th>
-                            <td mat-cell *matCellDef="let configurationEntry">
-                                <h4 style="margin-bottom: 0px">
-                                    {{ configurationEntry.providerType }}
-                                </h4>
-                            </td>
-                        </ng-container>
+                        <mat-icon>add</mat-icon>
+                        <span>{{ 'New' | translate }}</span>
+                    </button>
+                    <button
+                        mat-icon-button
+                        matTooltip="{{ 'Refresh' | translate }}"
+                        data-cy="refresh-export-providers-measures"
+                        (click)="loadAvailableExportProvider()"
+                    >
+                        <mat-icon>refresh</mat-icon>
+                    </button>
+                </div>
+                <table
+                    fxFlex="100"
+                    mat-table
+                    data-cy="exportproviders-settings"
+                    [dataSource]="dataSourceExport"
+                    style="width: 100%"
+                    matSort
+                >
+                    <ng-container matColumnDef="providertype">
+                        <th mat-header-cell mat-sort-header *matHeaderCellDef>
+                            {{ 'Provider Type' | translate }}
+                        </th>
+                        <td mat-cell *matCellDef="let configurationEntry">
+                            {{ configurationEntry.providerType }}
+                        </td>
+                    </ng-container>
 
-                        <ng-container matColumnDef="endpoint">
-                            <th
-                                mat-header-cell
-                                mat-sort-header
-                                *matHeaderCellDef
-                            >
-                                {{ 'Endpoint' | translate }}
-                            </th>
-                            <td mat-cell *matCellDef="let configurationEntry">
-                                {{ configurationEntry.endPoint }}
-                            </td>
-                        </ng-container>
+                    <ng-container matColumnDef="endpoint">
+                        <th mat-header-cell mat-sort-header *matHeaderCellDef>
+                            {{ 'Endpoint' | translate }}
+                        </th>
+                        <td mat-cell *matCellDef="let configurationEntry">
+                            {{ configurationEntry.endPoint }}
+                        </td>
+                    </ng-container>
 
-                        <ng-container matColumnDef="bucket">
-                            <th
-                                mat-header-cell
-                                mat-sort-header
-                                *matHeaderCellDef
-                            >
-                                {{ 'Bucket' | translate }}
-                            </th>
-                            <td mat-cell *matCellDef="let configurationEntry">
-                                {{ configurationEntry.bucketName }}
-                            </td>
-                        </ng-container>
+                    <ng-container matColumnDef="bucket">
+                        <th mat-header-cell mat-sort-header *matHeaderCellDef>
+                            {{ 'Bucket' | translate }}
+                        </th>
+                        <td mat-cell *matCellDef="let configurationEntry">
+                            {{ configurationEntry.bucketName }}
+                        </td>
+                    </ng-container>
 
-                        <ng-container matColumnDef="editExportProvider">
-                            <th mat-header-cell *matHeaderCellDef>
-                                {{ 'Edit' | translate }}
-                            </th>
-                            <td mat-cell *matCellDef="let configurationEntry">
-                                <div
-                                    *ngIf="
-                                        configurationEntry.providerId !==
-                                        'FOLDER'
-                                    "
-                                >
-                                    <div fxLayout="row">
-                                        <span
-                                            fxFlex
-                                            fxFlexOrder="3"
-                                            fxLayout="row"
-                                            fxLayoutAlign="start center"
+                    <ng-container matColumnDef="editExportProvider">
+                        <th mat-header-cell *matHeaderCellDef>
+                            {{ 'Edit' | translate }}
+                        </th>
+                        <td mat-cell *matCellDef="let configurationEntry">
+                            <div
+                                *ngIf="
+                                    configurationEntry.providerId !== 'FOLDER'
+                                "
+                            >
+                                <div fxLayout="row">
+                                    <span
+                                        fxFlex
+                                        fxFlexOrder="3"
+                                        fxLayout="row"
+                                        fxLayoutAlign="start center"
+                                    >
+                                        <button
+                                            color="accent"
+                                            mat-icon-button
+                                            matTooltip="{{
+                                                'Edit Export Provider'
+                                                    | translate
+                                            }}"
+                                            matTooltipPosition="above"
+                                            data-cy="exportProvider-edit-btn"
+                                            (click)="
+                                                createExportProvider(
+                                                    configurationEntry
+                                                )
+                                            "
                                         >
-                                            <button
-                                                color="accent"
-                                                mat-icon-button
-                                                matTooltip="{{
-                                                    'Edit Export Provider'
-                                                        | translate
-                                                }}"
-                                                matTooltipPosition="above"
-                                                
data-cy="exportProvider-edit-btn"
-                                                (click)="
-                                                    createExportProvider(
-                                                        configurationEntry
-                                                    )
-                                                "
-                                            >
-                                                <i class="material-icons"
-                                                    >edit</i
-                                                >
-                                            </button>
-                                        </span>
-                                    </div>
+                                            <i class="material-icons">edit</i>
+                                        </button>
+                                    </span>
                                 </div>
-                            </td>
-                        </ng-container>
+                            </div>
+                        </td>
+                    </ng-container>
 
-                        <ng-container matColumnDef="delete">
-                            <th mat-header-cell *matHeaderCellDef>
-                                {{ 'Remove' | translate }}
-                            </th>
-                            <td mat-cell *matCellDef="let configurationEntry">
-                                <div
-                                    *ngIf="
-                                        configurationEntry.providerId !==
-                                        'FOLDER'
-                                    "
-                                >
-                                    <div fxLayout="row">
-                                        <span
-                                            fxFlex
-                                            fxFlexOrder="3"
-                                            fxLayout="row"
-                                            fxLayoutAlign="start center"
+                    <ng-container matColumnDef="delete">
+                        <th mat-header-cell *matHeaderCellDef>
+                            {{ 'Remove' | translate }}
+                        </th>
+                        <td mat-cell *matCellDef="let configurationEntry">
+                            <div
+                                *ngIf="
+                                    configurationEntry.providerId !== 'FOLDER'
+                                "
+                            >
+                                <div fxLayout="row">
+                                    <span
+                                        fxFlex
+                                        fxFlexOrder="3"
+                                        fxLayout="row"
+                                        fxLayoutAlign="start center"
+                                    >
+                                        <button
+                                            color="accent"
+                                            mat-icon-button
+                                            matTooltip="{{
+                                                'Remove export provider 
configuration'
+                                                    | translate
+                                            }}"
+                                            data-cy="exportProvider-delete-btn"
+                                            matTooltipPosition="above"
+                                            (click)="
+                                                deleteExportProvider(
+                                                    
configurationEntry.providerId
+                                                )
+                                            "
                                         >
-                                            <button
-                                                color="accent"
-                                                mat-icon-button
-                                                matTooltip="{{
-                                                    'Remove export provider 
configuration'
-                                                        | translate
-                                                }}"
-                                                
data-cy="exportProvider-delete-btn"
-                                                matTooltipPosition="above"
-                                                (click)="
-                                                    deleteExportProvider(
-                                                        
configurationEntry.providerId
-                                                    )
-                                                "
-                                            >
-                                                <i class="material-icons"
-                                                    >delete</i
-                                                >
-                                            </button>
-                                        </span>
-                                    </div>
+                                            <i 
class="material-icons">delete</i>
+                                        </button>
+                                    </span>
                                 </div>
-                            </td>
-                        </ng-container>
+                            </div>
+                        </td>
+                    </ng-container>
 
-                        <tr
-                            mat-header-row
-                            *matHeaderRowDef="displayedColumnsExport"
-                        ></tr>
-                        <tr
-                            mat-row
-                            *matRowDef="
-                                let row;
-                                columns: displayedColumnsExport
-                            "
-                        ></tr>
-                    </table>
-                </div>
+                    <tr
+                        mat-header-row
+                        *matHeaderRowDef="displayedColumnsExport"
+                    ></tr>
+                    <tr
+                        mat-row
+                        *matRowDef="let row; columns: displayedColumnsExport"
+                    ></tr>
+                </table>
 
                 <div
                     *ngIf="
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 f7d50ee547..8473f8fe33 100644
--- a/ui/src/app/configuration/export/data-export-import.component.html
+++ b/ui/src/app/configuration/export/data-export-import.component.html
@@ -21,11 +21,10 @@
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
             <sp-split-section
                 [title]="'Export' | translate"
-                [subtitle]="'Export application data' | translate"
+                [subtitle]="
+                    'Export assets and all linked resources' | translate
+                "
             >
-                <div class="subsection-title">
-                    {{ 'Export assets and all linked resources' | translate }}
-                </div>
                 <div fxLayout="column" *ngFor="let asset of assets">
                     <mat-checkbox
                         (change)="handleSelectionChange($event, asset._id)"
@@ -55,12 +54,8 @@
         <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
             <sp-split-section
                 [title]="'Import' | translate"
-                [subtitle]="'Import application data' | translate"
+                [subtitle]="'Import from application package' | translate"
             >
-                <div class="subsection-title">
-                    {{ 'Import from application package' | translate }}
-                </div>
-
                 <div class="mt-10">
                     <button
                         mat-button
diff --git a/ui/src/app/configuration/files/files.component.html 
b/ui/src/app/configuration/files/files.component.html
index ba59132472..2cdd9b2a8a 100644
--- a/ui/src/app/configuration/files/files.component.html
+++ b/ui/src/app/configuration/files/files.component.html
@@ -24,9 +24,13 @@
                 | translate
         "
     >
-        <div fxLayout="row" fxLayoutAlign="start start" fxLayoutGap="10px">
+        <div
+            fxLayout="row"
+            fxLayoutAlign="start start"
+            fxLayoutGap="10px"
+            section-actions
+        >
             <button
-                mat-button
                 mat-flat-button
                 color="accent"
                 (click)="openFileUploadDialog()"
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 5b196082f1..7094ab15ae 100644
--- 
a/ui/src/app/configuration/general-configuration/general-configuration.component.html
+++ 
b/ui/src/app/configuration/general-configuration/general-configuration.component.html
@@ -23,7 +23,12 @@
             fxLayoutAlign="start start"
             *ngIf="formReady"
         >
-            <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
+            <form
+                [formGroup]="parentForm"
+                fxFlex="100"
+                fxLayout="column"
+                class="w-100"
+            >
                 <sp-split-section
                     [title]="'Basic' | translate"
                     [subtitle]="'Basic settings' | translate"
@@ -37,66 +42,87 @@
                                 | translate
                         }}
                     </div>
-                    <div class="subsection-title">
-                        {{ 'App Name' | translate }}
-                    </div>
-                    <mat-form-field appearance="outline">
-                        <input
-                            formControlName="appName"
-                            fxFlex
-                            matInput
-                            required
-                            data-cy="general-config-app-name"
-                        />
-                    </mat-form-field>
-                    <div class="subsection-title">
-                        {{ 'Host and Port' | translate }}
+                    <div
+                        fxLayout="row"
+                        fxLayoutAlign="start center"
+                        fxLayoutGap="10px"
+                    >
+                        <div class="subsection-title">
+                            {{ 'App Name' | translate }}
+                        </div>
+                        <mat-form-field appearance="outline" fxFlex>
+                            <input
+                                formControlName="appName"
+                                fxFlex
+                                matInput
+                                required
+                                data-cy="general-config-app-name"
+                            />
+                        </mat-form-field>
                     </div>
-                    <div fxLayout="column" fxFlex="100">
-                        <div fxLayout="row">
-                            <div fxLayout="row" fxLayoutAlign="start center">
-                                <mat-button-toggle-group
-                                    name="protocol"
-                                    [attr.aria-label]="'Protocol' | translate"
-                                    formControlName="protocol"
+                    <div
+                        fxLayout="row"
+                        fxLayoutAlign="start center"
+                        fxLayoutGap="10px"
+                    >
+                        <div class="subsection-title">
+                            {{ 'Host and Port' | translate }}
+                        </div>
+                        <div fxLayout="column" fxFlex="100">
+                            <div fxLayout="row">
+                                <div
+                                    fxLayout="row"
+                                    fxLayoutAlign="start center"
+                                >
+                                    <mat-button-toggle-group
+                                        name="protocol"
+                                        [attr.aria-label]="
+                                            'Protocol' | translate
+                                        "
+                                        formControlName="protocol"
+                                    >
+                                        <mat-button-toggle value="http"
+                                            >http
+                                        </mat-button-toggle>
+                                        <mat-button-toggle value="https"
+                                            >https
+                                        </mat-button-toggle>
+                                    </mat-button-toggle-group>
+                                </div>
+                                <mat-form-field
+                                    color="accent"
+                                    class="ml-10"
+                                    subscriptSizing="dynamic"
+                                >
+                                    <mat-label>{{
+                                        'Host' | translate
+                                    }}</mat-label>
+                                    <input
+                                        formControlName="hostname"
+                                        fxFlex
+                                        matInput
+                                        required
+                                        data-cy="general-config-hostname"
+                                    />
+                                </mat-form-field>
+                                <mat-form-field
+                                    color="accent"
+                                    class="ml-10"
+                                    subscriptSizing="dynamic"
                                 >
-                                    <mat-button-toggle value="http"
-                                        >http
-                                    </mat-button-toggle>
-                                    <mat-button-toggle value="https"
-                                        >https
-                                    </mat-button-toggle>
-                                </mat-button-toggle-group>
+                                    <mat-label>{{
+                                        'Port' | translate
+                                    }}</mat-label>
+                                    <input
+                                        formControlName="port"
+                                        fxFlex
+                                        matInput
+                                        type="number"
+                                        required
+                                        data-cy="general-config-port"
+                                    />
+                                </mat-form-field>
                             </div>
-                            <mat-form-field
-                                color="accent"
-                                class="ml-10"
-                                subscriptSizing="dynamic"
-                            >
-                                <mat-label>{{ 'Host' | translate }}</mat-label>
-                                <input
-                                    formControlName="hostname"
-                                    fxFlex
-                                    matInput
-                                    required
-                                    data-cy="general-config-hostname"
-                                />
-                            </mat-form-field>
-                            <mat-form-field
-                                color="accent"
-                                class="ml-10"
-                                subscriptSizing="dynamic"
-                            >
-                                <mat-label>{{ 'Port' | translate }}</mat-label>
-                                <input
-                                    formControlName="port"
-                                    fxFlex
-                                    matInput
-                                    type="number"
-                                    required
-                                    data-cy="general-config-port"
-                                />
-                            </mat-form-field>
                         </div>
                     </div>
                 </sp-split-section>
@@ -160,20 +186,19 @@
                 </sp-configuration-link-settings>
                 <sp-user-acknowledgment [parentForm]="parentForm">
                 </sp-user-acknowledgment>
-                <sp-split-section>
-                    <div class="mt-10">
-                        <button
-                            mat-flat-button
-                            (click)="updateConfig()"
-                            style="margin-right: 10px"
-                            [disabled]="parentForm.invalid"
-                            data-cy="sp-element-general-config-save"
-                        >
-                            <i class="material-icons">save</i
-                            ><span>&nbsp;{{ 'Save' | translate }}</span>
-                        </button>
-                    </div>
-                </sp-split-section>
+
+                <div class="mt-10">
+                    <button
+                        mat-flat-button
+                        (click)="updateConfig()"
+                        style="margin-right: 10px"
+                        [disabled]="parentForm.invalid"
+                        data-cy="sp-element-general-config-save"
+                    >
+                        <i class="material-icons">save</i
+                        ><span>&nbsp;{{ 'Save' | translate }}</span>
+                    </button>
+                </div>
             </form>
         </div>
     </div>
diff --git 
a/ui/src/app/configuration/general-configuration/link-settings/link-settings.component.html
 
b/ui/src/app/configuration/general-configuration/link-settings/link-settings.component.html
index e78775a339..a601a5ad07 100644
--- 
a/ui/src/app/configuration/general-configuration/link-settings/link-settings.component.html
+++ 
b/ui/src/app/configuration/general-configuration/link-settings/link-settings.component.html
@@ -21,9 +21,8 @@
     [subtitle]="'Configure application links' | translate"
     [formGroup]="parentForm"
 >
-    <div class="subsection-title">{{ 'Documentation Link' | translate }}</div>
-    <mat-form-field color="accent">
-        <mat-label>{{ 'Documentation URL' | translate }}</mat-label>
+    <mat-form-field color="accent" class="mt-10">
+        <mat-label>{{ 'Documentation Link' | translate }}</mat-label>
         <input formControlName="documentationUrl" fxFlex matInput />
     </mat-form-field>
     <mat-checkbox formControlName="showDocumentationLinkOnStartScreen"
@@ -33,16 +32,12 @@
         >{{ 'Show documentation link in user menu' | translate }}
     </mat-checkbox>
 
-    <div class="subsection-title mt-10">
-        {{ 'API Documentation Link' | translate }}
-    </div>
     <mat-checkbox formControlName="showApiDocumentationLinkOnStartScreen"
         >{{ 'Show API documentation link on login page' | translate }}
     </mat-checkbox>
 
-    <div class="subsection-title mt-10">{{ 'Support Link' | translate }}</div>
-    <mat-form-field color="accent">
-        <mat-label>{{ 'Support URL' | translate }}</mat-label>
+    <mat-form-field color="accent" class="mt-10">
+        <mat-label>{{ 'Support Link' | translate }}</mat-label>
         <input formControlName="supportUrl" fxFlex matInput />
     </mat-form-field>
     <mat-checkbox formControlName="showSupportUrlOnStartScreen"
diff --git 
a/ui/src/app/configuration/label-configuration/label-configuration.component.html
 
b/ui/src/app/configuration/label-configuration/label-configuration.component.html
index e4d5dc7bd1..d55be91c0e 100644
--- 
a/ui/src/app/configuration/label-configuration/label-configuration.component.html
+++ 
b/ui/src/app/configuration/label-configuration/label-configuration.component.html
@@ -25,7 +25,12 @@
                     | translate
             "
         >
-            <div fxLayout="row" fxLayoutAlign="start start" fxLayoutGap="10px">
+            <div
+                fxLayout="row"
+                fxLayoutAlign="start start"
+                fxLayoutGap="10px"
+                section-actions
+            >
                 <button
                     mat-button
                     mat-flat-button
@@ -34,7 +39,7 @@
                     (click)="createLabelMode = true"
                 >
                     <i class="material-icons">add</i
-                    ><span>&nbsp;{{ 'New label' | translate }}</span>
+                    ><span>&nbsp;{{ 'New' | translate }}</span>
                 </button>
             </div>
             <div *ngIf="createLabelMode" class="mb-10">
@@ -43,9 +48,6 @@
                     (saveEmitter)="saveLabel($event)"
                 ></sp-edit-label>
             </div>
-            <div class="subsection-title mt-10">
-                {{ 'Available labels' | translate }}
-            </div>
             <div
                 fxLayout="column"
                 *ngFor="let label of allLabels"
diff --git 
a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
 
b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
index 6d6c24d681..3a1eab80dc 100644
--- 
a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
+++ 
b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
@@ -24,12 +24,7 @@
                 'Manage Kafka settings for pipeline communication' | translate
             "
         >
-            <div
-                fxFlex="100"
-                fxLayout="column"
-                fxLayoutAlign="start start"
-                class="page-container-padding-inner"
-            >
+            <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
                 <form
                     (ngSubmit)="updateMessagingSettings()"
                     class="form-width"
@@ -80,7 +75,8 @@
                             type="submit"
                             class="md-raised md-primary submit-button"
                         >
-                            {{ 'Update' | translate }}
+                            <mat-icon>save</mat-icon>
+                            <span>{{ 'Save' | translate }}</span>
                         </button>
                     </div>
                 </form>
@@ -92,12 +88,7 @@
             [title]="'Protocols' | translate"
             [subtitle]="'Manage the priority of protocols used' | translate"
         >
-            <div
-                fxFlex="100"
-                fxLayout="column"
-                fxLayoutAlign="start start"
-                class="page-container-padding-inner"
-            >
+            <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
                 <div
                     cdkDropList
                     class="data-format-list"
@@ -122,7 +113,8 @@
                         class="md-raised md-primary submit-button"
                         (click)="updateMessagingSettings()"
                     >
-                        {{ 'Update' | translate }}
+                        <mat-icon>save</mat-icon>
+                        <span>{{ 'Save' | translate }}</span>
                     </button>
                 </div>
             </div>
@@ -172,7 +164,8 @@
                     class="md-raised md-primary submit-button"
                     (click)="updateMessagingSettings()"
                 >
-                    {{ 'Update' | translate }}
+                    <mat-icon>save</mat-icon>
+                    <span>{{ 'Save' | translate }}</span>
                 </button>
             </div>
         </sp-split-section>
diff --git 
a/ui/src/app/configuration/security-configuration/abstract-security-principal-config.ts
 
b/ui/src/app/configuration/security-configuration/abstract-security-principal-config.ts
index c9b641f282..7fe7f9872f 100644
--- 
a/ui/src/app/configuration/security-configuration/abstract-security-principal-config.ts
+++ 
b/ui/src/app/configuration/security-configuration/abstract-security-principal-config.ts
@@ -64,7 +64,7 @@ export abstract class AbstractSecurityPrincipalConfig<
                 ? this.translateService.instant('Edit user {{user}}', {
                       user: user.username,
                   })
-                : this.translateService.instant('Add group'),
+                : this.translateService.instant('Add user'),
             width: '50vw',
             data: {
                 user: user,
diff --git 
a/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.html
 
b/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.html
index 05fdc74d94..4b945f4333 100644
--- 
a/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.html
+++ 
b/ui/src/app/configuration/security-configuration/role-configuration/role-configuration.component.html
@@ -17,17 +17,6 @@
   -->
 
 <div fxLayout="column">
-    <div>
-        <button
-            mat-button
-            mat-flat-button
-            color="accent"
-            (click)="createRole()"
-        >
-            <i class="material-icons">add</i
-            ><span>&nbsp;{{ 'New Role' | translate }}</span>
-        </button>
-    </div>
     <div fxFlex="100" fxLayout="column">
         <sp-table
             *ngIf="dataSource"
@@ -63,9 +52,7 @@
             </ng-container>
 
             <ng-container matColumnDef="edit">
-                <th mat-header-cell *matHeaderCellDef class="text-right">
-                    {{ 'Actions' | translate }}
-                </th>
+                <th mat-header-cell *matHeaderCellDef class="text-right"></th>
                 <td mat-cell *matCellDef="let role">
                     <div fxLayout="row">
                         <span
@@ -76,7 +63,7 @@
                         >
                             <div class="mr-15">
                                 <button
-                                    color="accent"
+                                    class="mat-basic"
                                     mat-flat-button
                                     [matTooltip]="'Edit user' | translate"
                                     matTooltipPosition="above"
diff --git 
a/ui/src/app/configuration/security-configuration/security-configuration.component.html
 
b/ui/src/app/configuration/security-configuration/security-configuration.component.html
index e78620a40f..39cd523077 100644
--- 
a/ui/src/app/configuration/security-configuration/security-configuration.component.html
+++ 
b/ui/src/app/configuration/security-configuration/security-configuration.component.html
@@ -23,9 +23,15 @@
                 [title]="'User Accounts' | translate"
                 [subtitle]="'Add and edit user accounts' | translate"
             >
-                <div class="subsection-title">
-                    {{ 'Existing user accounts' | translate }}
-                </div>
+                <button
+                    section-actions
+                    mat-flat-button
+                    data-cy="add-new-user"
+                    (click)="createUserAccount()"
+                >
+                    <i class="material-icons">add</i
+                    ><span>&nbsp;{{ 'New' | translate }}</span>
+                </button>
                 <sp-security-user-config></sp-security-user-config>
             </sp-split-section>
         </div>
@@ -35,9 +41,16 @@
                 [title]="'Service Accounts' | translate"
                 [subtitle]="'Add and edit service accounts' | translate"
             >
-                <div class="subsection-title">
-                    {{ 'Existing service accounts' | translate }}
-                </div>
+                <button
+                    section-actions
+                    mat-button
+                    mat-flat-button
+                    color="accent"
+                    (click)="createServiceAccount()"
+                >
+                    <i class="material-icons">add</i
+                    ><span>&nbsp;{{ 'New' | translate }}</span>
+                </button>
                 <sp-security-service-config></sp-security-service-config>
             </sp-split-section>
         </div>
@@ -47,9 +60,17 @@
                 [title]="'Groups' | translate"
                 [subtitle]="'Manage user groups' | translate"
             >
-                <div class="subsection-title">
-                    {{ 'Existing groups' | translate }}
-                </div>
+                <button
+                    section-actions
+                    mat-button
+                    mat-flat-button
+                    color="accent"
+                    data-cy="new-user-group-btn"
+                    (click)="createGroup()"
+                >
+                    <i class="material-icons">add</i
+                    ><span>&nbsp;{{ 'New' | translate }}</span>
+                </button>
                 <sp-security-user-group-config></sp-security-user-group-config>
             </sp-split-section>
         </div>
@@ -58,9 +79,16 @@
                 [title]="'Roles' | translate"
                 [subtitle]="'Manage roles' | translate"
             >
-                <div class="subsection-title">
-                    {{ 'Existing roles' | translate }}
-                </div>
+                <button
+                    section-actions
+                    mat-button
+                    mat-flat-button
+                    color="accent"
+                    (click)="createRole()"
+                >
+                    <i class="material-icons">add</i
+                    ><span>&nbsp;{{ 'New' | translate }}</span>
+                </button>
                 <sp-security-role-config></sp-security-role-config>
             </sp-split-section>
         </div>
diff --git 
a/ui/src/app/configuration/security-configuration/security-configuration.component.ts
 
b/ui/src/app/configuration/security-configuration/security-configuration.component.ts
index 3cb21190d6..07ee348127 100644
--- 
a/ui/src/app/configuration/security-configuration/security-configuration.component.ts
+++ 
b/ui/src/app/configuration/security-configuration/security-configuration.component.ts
@@ -16,10 +16,14 @@
  *
  */
 
-import { Component, OnInit } from '@angular/core';
+import { Component, inject, OnInit, ViewChild } from '@angular/core';
 import { SpConfigurationTabsService } from '../configuration-tabs.service';
 import { SpBreadcrumbService, SpNavigationItem } from '@streampipes/shared-ui';
 import { SpConfigurationRoutes } from '../configuration.routes';
+import { SecurityUserConfigComponent } from 
'./security-user-configuration/security-user-config.component';
+import { SecurityServiceConfigComponent } from 
'./security-service-configuration/security-service-config.component';
+import { SecurityRoleConfigComponent } from 
'./role-configuration/role-configuration.component';
+import { SecurityUserGroupConfigComponent } from 
'./user-group-configuration/user-group-configuration.component';
 
 @Component({
     selector: 'sp-security-configuration',
@@ -30,10 +34,17 @@ import { SpConfigurationRoutes } from 
'../configuration.routes';
 export class SecurityConfigurationComponent implements OnInit {
     tabs: SpNavigationItem[] = [];
 
-    constructor(
-        private breadcrumbService: SpBreadcrumbService,
-        private tabService: SpConfigurationTabsService,
-    ) {}
+    private breadcrumbService = inject(SpBreadcrumbService);
+    private tabService = inject(SpConfigurationTabsService);
+
+    @ViewChild(SecurityUserConfigComponent)
+    userConfig!: SecurityUserConfigComponent;
+    @ViewChild(SecurityServiceConfigComponent)
+    serviceConfig!: SecurityServiceConfigComponent;
+    @ViewChild(SecurityRoleConfigComponent)
+    roleConfig!: SecurityRoleConfigComponent;
+    @ViewChild(SecurityUserGroupConfigComponent)
+    groupConfig!: SecurityUserGroupConfigComponent;
 
     ngOnInit(): void {
         this.tabs = this.tabService.getTabs();
@@ -42,4 +53,20 @@ export class SecurityConfigurationComponent implements 
OnInit {
             { label: this.tabService.getTabTitle('security') },
         ]);
     }
+
+    createUserAccount(): void {
+        this.userConfig.createUser();
+    }
+
+    createServiceAccount(): void {
+        this.serviceConfig.createUser();
+    }
+
+    createGroup(): void {
+        this.groupConfig.createGroup();
+    }
+
+    createRole(): void {
+        this.roleConfig.createRole();
+    }
 }
diff --git 
a/ui/src/app/configuration/security-configuration/security-service-configuration/security-service-config.component.html
 
b/ui/src/app/configuration/security-configuration/security-service-configuration/security-service-config.component.html
index 00d9337fd9..5d6b4b9e39 100644
--- 
a/ui/src/app/configuration/security-configuration/security-service-configuration/security-service-config.component.html
+++ 
b/ui/src/app/configuration/security-configuration/security-service-configuration/security-service-config.component.html
@@ -17,17 +17,7 @@
   -->
 
 <div fxLayout="column">
-    <div>
-        <button
-            mat-button
-            mat-flat-button
-            color="accent"
-            (click)="createUser()"
-        >
-            <i class="material-icons">add</i
-            ><span>&nbsp;{{ 'New Service Account' | translate }}</span>
-        </button>
-    </div>
+    <div></div>
     <div fxFlex="100" fxLayout="column">
         <sp-table
             *ngIf="dataSource"
@@ -46,9 +36,7 @@
             </ng-container>
 
             <ng-container matColumnDef="edit">
-                <th mat-header-cell *matHeaderCellDef class="text-right">
-                    {{ 'Actions' | translate }}
-                </th>
+                <th mat-header-cell *matHeaderCellDef class="text-right"></th>
                 <td mat-cell *matCellDef="let account">
                     <div fxLayout="row">
                         <span
diff --git 
a/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
 
b/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
index 2c5939a16c..7ddef77d55 100644
--- 
a/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
+++ 
b/ui/src/app/configuration/security-configuration/security-user-configuration/security-user-config.component.html
@@ -17,12 +17,6 @@
   -->
 
 <div fxLayout="column">
-    <div>
-        <button mat-flat-button data-cy="add-new-user" (click)="createUser()">
-            <i class="material-icons">add</i
-            ><span>&nbsp;{{ 'New User' | translate }}</span>
-        </button>
-    </div>
     <div fxFlex="100" fxLayout="column">
         <sp-table
             *ngIf="dataSource"
@@ -95,9 +89,7 @@
             </ng-container>
 
             <ng-container matColumnDef="edit">
-                <th mat-header-cell *matHeaderCellDef class="text-right">
-                    {{ 'Actions' | translate }}
-                </th>
+                <th mat-header-cell *matHeaderCellDef class="text-right"></th>
                 <td mat-cell *matCellDef="let account">
                     <div fxLayout="row">
                         <span
diff --git 
a/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.html
 
b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.html
index 82f6c62c50..aef0da3194 100644
--- 
a/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.html
+++ 
b/ui/src/app/configuration/security-configuration/user-group-configuration/user-group-configuration.component.html
@@ -17,18 +17,6 @@
   -->
 
 <div fxLayout="column">
-    <div>
-        <button
-            mat-button
-            mat-flat-button
-            color="accent"
-            data-cy="new-user-group-btn"
-            (click)="createGroup()"
-        >
-            <i class="material-icons">add</i
-            ><span>&nbsp;{{ 'New User Group' | translate }}</span>
-        </button>
-    </div>
     <div fxFlex="100" fxLayout="column">
         <sp-table
             *ngIf="dataSource"
@@ -56,9 +44,7 @@
             </ng-container>
 
             <ng-container matColumnDef="edit">
-                <th mat-header-cell *matHeaderCellDef class="text-right">
-                    {{ 'Actions' | translate }}
-                </th>
+                <th mat-header-cell *matHeaderCellDef class="text-right"></th>
                 <td mat-cell *matCellDef="let group">
                     <div fxLayout="row">
                         <span
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 37eca8772c..c3323d621b 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
@@ -17,17 +17,17 @@
   -->
 
 <div fxLayout="column">
-    <form
-        [formGroup]="locationForm"
-        fxFlex="100"
-        fxLayout="column"
-        *ngIf="locationConfig"
+    <sp-split-section
+        [title]="'Geo features' | translate"
+        [subtitle]="
+            'Geo features are used to better organize assets.' | translate
+        "
     >
-        <sp-split-section
-            [title]="'Geo features' | translate"
-            [subtitle]="
-                'Geo features are used to better organize assets.' | translate
-            "
+        <form
+            [formGroup]="locationForm"
+            fxFlex="100"
+            fxLayout="column"
+            *ngIf="locationConfig"
         >
             <mat-checkbox
                 formControlName="locationFeaturesEnabled"
@@ -72,19 +72,18 @@
                     />
                 </mat-form-field>
             </div>
-        </sp-split-section>
-        <sp-split-section>
-            <div>
-                <button
-                    mat-flat-button
-                    color="accent"
-                    data-cy="sites-location-features-button"
-                    [disabled]="!locationForm.valid"
-                    (click)="save()"
-                >
-                    {{ 'Save' | translate }}
-                </button>
-            </div>
-        </sp-split-section>
-    </form>
+        </form>
+        <div class="mt-10">
+            <button
+                mat-flat-button
+                color="accent"
+                data-cy="sites-location-features-button"
+                [disabled]="!locationForm.valid"
+                (click)="save()"
+            >
+                <mat-icon>save</mat-icon>
+                <span>{{ 'Save' | translate }}</span>
+            </button>
+        </div>
+    </sp-split-section>
 </div>
diff --git 
a/ui/src/app/configuration/sites-configuration/site-area-configuration/site-area-configuration.component.html
 
b/ui/src/app/configuration/sites-configuration/site-area-configuration/site-area-configuration.component.html
index 7c07eefc71..745081d59a 100644
--- 
a/ui/src/app/configuration/sites-configuration/site-area-configuration/site-area-configuration.component.html
+++ 
b/ui/src/app/configuration/sites-configuration/site-area-configuration/site-area-configuration.component.html
@@ -22,17 +22,17 @@
         'Manage your organization\'s sites and production areas' | translate
     "
 >
-    <div fxLayout="row">
-        <button
-            mat-flat-button
-            color="accent"
-            data-cy="sites-manage-sites-button"
-            (click)="openManageSitesDialog(undefined)"
-        >
-            <mat-icon>add</mat-icon>
-            <span>{{ 'New site' | translate }}</span>
-        </button>
-    </div>
+    <button
+        section-actions
+        mat-flat-button
+        color="accent"
+        data-cy="sites-manage-sites-button"
+        (click)="openManageSitesDialog(undefined)"
+    >
+        <mat-icon>add</mat-icon>
+        <span>{{ 'New' | translate }}</span>
+    </button>
+
     <sp-table
         class="mt-10"
         [dataSource]="dataSource"
diff --git a/ui/src/scss/sp/main.scss b/ui/src/scss/sp/main.scss
index f12b005b5c..33f425d539 100644
--- a/ui/src/scss/sp/main.scss
+++ b/ui/src/scss/sp/main.scss
@@ -163,8 +163,8 @@ md-content {
 }
 
 .subsection-title {
-    font-size: 12pt;
-    font-weight: bold;
+    //font-weight: 300;
+    font-size: var(--mat-sys-body-medium-size);
     margin-bottom: 10px;
 }
 

Reply via email to