You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streampipes.apache.org by ze...@apache.org on 2022/05/16 14:08:02 UTC

[incubator-streampipes] 01/01: [STREAMPIPES-537] Change router for configuration

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

zehnder pushed a commit to branch STREAMPIPES-537
in repository https://gitbox.apache.org/repos/asf/incubator-streampipes.git

commit 83691084958761cacd6cdc9bef9d156ee98779c3
Author: Philipp Zehnder <ze...@fzi.de>
AuthorDate: Mon May 16 16:07:42 2022 +0200

    [STREAMPIPES-537] Change router for configuration
---
 .../app/configuration/configuration.component.html |  69 +++----
 .../app/configuration/configuration.component.ts   |  13 +-
 ui/src/app/configuration/configuration.module.ts   | 120 ++++++++-----
 .../datalake-configuration.component.html          | 149 +++++++--------
 .../email-configuration.component.html             | 199 ++++++++++-----------
 .../general-configuration.component.html           | 140 +++++++--------
 .../messaging-configuration.component.html         | 125 ++++++-------
 .../pipeline-element-configuration.component.html  |  93 +++++-----
 .../security-configuration.component.html          |  62 ++++---
 9 files changed, 484 insertions(+), 486 deletions(-)

diff --git a/ui/src/app/configuration/configuration.component.html b/ui/src/app/configuration/configuration.component.html
index 026c76f51..e1f287e73 100644
--- a/ui/src/app/configuration/configuration.component.html
+++ b/ui/src/app/configuration/configuration.component.html
@@ -19,43 +19,44 @@
 <div fxLayout="column" class="page-container">
     <div fxLayout="row" class="p-0 sp-bg-lightgray page-container-nav">
         <div fxLayout="fill">
-            <mat-tab-group [selectedIndex]="selectedIndex" (selectedIndexChange)="selectedIndexChange($event)"
-                           color="accent">
-                <mat-tab label="General"></mat-tab>
-                <mat-tab label="DataLake"></mat-tab>
-                <mat-tab label="Mail"></mat-tab>
-                <mat-tab label="Messaging"></mat-tab>
-                <mat-tab label="Pipeline Element Configuration"></mat-tab>
-                <mat-tab label="Security"></mat-tab>
-            </mat-tab-group>
+            <div fxFlex="100" class="page-container-nav">
+                <nav mat-tab-nav-bar color="accent">
+                  <a mat-tab-link
+                     (click)="navigateTo('general')"
+                     [active]="activeLink === 'general'"> 
+                      General
+                  </a>
+                  <a mat-tab-link
+                     (click)="navigateTo('datalake')"
+                     [active]="activeLink === 'datalake'"> 
+                      DataLake
+                  </a>
+                  <a mat-tab-link
+                     (click)="navigateTo('email')"
+                     [active]="activeLink === 'email'"> 
+                      Mail
+                  </a>
+                  <a mat-tab-link
+                     (click)="navigateTo('messaging')"
+                     [active]="activeLink === 'messaging'"> 
+                      Messaging
+                  </a>
+                  <a mat-tab-link
+                     (click)="navigateTo('pipelineelement')"
+                     [active]="activeLink === 'pipelineelement'"> 
+                      Pipeline Element Configuration
+                  </a>
+                  <a mat-tab-link
+                     (click)="navigateTo('security')"
+                     [active]="activeLink === 'security'"> 
+                     Security 
+                  </a>
+                </nav>
+              </div>
         </div>
     </div>
 
     <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100">
-        <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100"
-             *ngIf="selectedIndex == 0">
-            <sp-general-configuration fxFlex="100"></sp-general-configuration>
-        </div>
-        <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100"
-             *ngIf="selectedIndex == 1">
-            <sp-datalake-configuration fxFlex="100"></sp-datalake-configuration>
-        </div>
-        <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100"
-             *ngIf="selectedIndex == 2">
-            <sp-email-configuration fxFlex="100"></sp-email-configuration>
-        </div>
-        <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100"
-             *ngIf="selectedIndex == 3">
-            <messaging-configuration fxFlex="100"></messaging-configuration>
-        </div>
-        <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100"
-             *ngIf="selectedIndex == 4">
-            <pipeline-element-configuration fxFlex="100"></pipeline-element-configuration>
-        </div>
-        <div class="fixed-height page-container-padding-inner" fxLayout="column" fxFlex="100"
-             *ngIf="selectedIndex == 5">
-            <sp-security-configuration fxFlex="100"></sp-security-configuration>
-        </div>
+        <ng-content fxFlex="100"></ng-content>
     </div>
-
 </div>
diff --git a/ui/src/app/configuration/configuration.component.ts b/ui/src/app/configuration/configuration.component.ts
index fdf7d4d36..6265c82e7 100644
--- a/ui/src/app/configuration/configuration.component.ts
+++ b/ui/src/app/configuration/configuration.component.ts
@@ -16,10 +16,12 @@
  *
  */
 
-import { Component } from '@angular/core';
+import { Component, Input } from '@angular/core';
 import { animate, state, style, transition, trigger } from '@angular/animations';
+import { Router } from '@angular/router';
 
 @Component({
+    selector: 'sp-configuration-component',
     templateUrl: './configuration.component.html',
     styleUrls: ['./configuration.component.css'],
     animations: [
@@ -32,13 +34,14 @@ import { animate, state, style, transition, trigger } from '@angular/animations'
 })
 export class ConfigurationComponent {
 
-    selectedIndex = 0;
+    @Input()
+    activeLink: string;
 
-    constructor() {
+    constructor(private router: Router) {
     }
 
-    selectedIndexChange(index: number) {
-        this.selectedIndex = index;
+    navigateTo(routeId: string): void {
+      this.router.navigate(['configuration', routeId]);
     }
 
 }
diff --git a/ui/src/app/configuration/configuration.module.ts b/ui/src/app/configuration/configuration.module.ts
index 864d91863..88e351b1f 100644
--- a/ui/src/app/configuration/configuration.module.ts
+++ b/ui/src/app/configuration/configuration.module.ts
@@ -16,46 +16,45 @@
  *
  */
 
-import { NgModule } from '@angular/core';
-import { MatButtonModule } from '@angular/material/button';
-import { MatCheckboxModule } from '@angular/material/checkbox';
-import { MatGridListModule } from '@angular/material/grid-list';
-import { MatIconModule } from '@angular/material/icon';
-import { MatInputModule } from '@angular/material/input';
-import { MatTooltipModule } from '@angular/material/tooltip';
-import { FlexLayoutModule } from '@angular/flex-layout';
-import { CommonModule } from '@angular/common';
-import { FormsModule, ReactiveFormsModule } from '@angular/forms';
+import { NgModule } from "@angular/core";
+import { MatButtonModule } from "@angular/material/button";
+import { MatCheckboxModule } from "@angular/material/checkbox";
+import { MatGridListModule } from "@angular/material/grid-list";
+import { MatIconModule } from "@angular/material/icon";
+import { MatInputModule } from "@angular/material/input";
+import { MatTooltipModule } from "@angular/material/tooltip";
+import { FlexLayoutModule } from "@angular/flex-layout";
+import { CommonModule } from "@angular/common";
+import { FormsModule, ReactiveFormsModule } from "@angular/forms";
 
-import { ConfigurationComponent } from './configuration.component';
-import { ConfigurationService } from './shared/configuration.service';
-import { ConsulServiceComponent } from './consul-service/consul-service.component';
-import { ConsulConfigsComponent } from './consul-configs/consul-configs.component';
-import { ConsulConfigsTextComponent } from './consul-configs-text/consul-configs-text.component';
-import { ConsulConfigsPasswordComponent } from './consul-configs-password/consul-configs-password.component';
-import { ConsulConfigsBooleanComponent } from './consul-configs-boolean/consul-configs-boolean.component';
-import { ConsulConfigsNumberComponent } from './consul-configs-number/consul-configs-number.component';
-import { CustomMaterialModule } from '../CustomMaterial/custom-material.module';
-import { PipelineElementConfigurationComponent } from './pipeline-element-configuration/pipeline-element-configuration.component';
-import { MessagingConfigurationComponent } from './messaging-configuration/messaging-configuration.component';
-import { DragDropModule } from '@angular/cdk/drag-drop';
-import { DatalakeConfigurationComponent } from './datalake-configuration/datalake-configuration.component';
-import { DeleteDatalakeIndexComponent } from './dialog/delete-datalake-index/delete-datalake-index-dialog.component';
-import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
-import { SecurityConfigurationComponent } from './security-configuration/security-configuration.component';
-import { CoreUiModule } from '../core-ui/core-ui.module';
-import { MatDividerModule } from '@angular/material/divider';
-import { SecurityUserConfigComponent } from './security-configuration/security-user-configuration/security-user-config.component';
-import { SecurityServiceConfigComponent } from './security-configuration/security-service-configuration/security-service-config.component';
-import { EditUserDialogComponent } from './security-configuration/edit-user-dialog/edit-user-dialog.component';
-import { PlatformServicesModule } from '@streampipes/platform-services';
-import { SecurityUserGroupConfigComponent } from './security-configuration/user-group-configuration/user-group-configuration.component';
-import { EditGroupDialogComponent } from './security-configuration/edit-group-dialog/edit-group-dialog.component';
-import { EmailConfigurationComponent } from './email-configuration/email-configuration.component';
-import { GeneralConfigurationComponent } from './general-configuration/general-configuration.component';
-import {
-  SecurityAuthenticationConfigurationComponent
-} from './security-configuration/authentication-configuration/authentication-configuration.component';
+import { ConfigurationComponent } from "./configuration.component";
+import { ConfigurationService } from "./shared/configuration.service";
+import { ConsulServiceComponent } from "./consul-service/consul-service.component";
+import { ConsulConfigsComponent } from "./consul-configs/consul-configs.component";
+import { ConsulConfigsTextComponent } from "./consul-configs-text/consul-configs-text.component";
+import { ConsulConfigsPasswordComponent } from "./consul-configs-password/consul-configs-password.component";
+import { ConsulConfigsBooleanComponent } from "./consul-configs-boolean/consul-configs-boolean.component";
+import { ConsulConfigsNumberComponent } from "./consul-configs-number/consul-configs-number.component";
+import { CustomMaterialModule } from "../CustomMaterial/custom-material.module";
+import { PipelineElementConfigurationComponent } from "./pipeline-element-configuration/pipeline-element-configuration.component";
+import { MessagingConfigurationComponent } from "./messaging-configuration/messaging-configuration.component";
+import { DragDropModule } from "@angular/cdk/drag-drop";
+import { DatalakeConfigurationComponent } from "./datalake-configuration/datalake-configuration.component";
+import { DeleteDatalakeIndexComponent } from "./dialog/delete-datalake-index/delete-datalake-index-dialog.component";
+import { MatProgressSpinnerModule } from "@angular/material/progress-spinner";
+import { SecurityConfigurationComponent } from "./security-configuration/security-configuration.component";
+import { CoreUiModule } from "../core-ui/core-ui.module";
+import { MatDividerModule } from "@angular/material/divider";
+import { SecurityUserConfigComponent } from "./security-configuration/security-user-configuration/security-user-config.component";
+import { SecurityServiceConfigComponent } from "./security-configuration/security-service-configuration/security-service-config.component";
+import { EditUserDialogComponent } from "./security-configuration/edit-user-dialog/edit-user-dialog.component";
+import { PlatformServicesModule } from "@streampipes/platform-services";
+import { SecurityUserGroupConfigComponent } from "./security-configuration/user-group-configuration/user-group-configuration.component";
+import { EditGroupDialogComponent } from "./security-configuration/edit-group-dialog/edit-group-dialog.component";
+import { EmailConfigurationComponent } from "./email-configuration/email-configuration.component";
+import { GeneralConfigurationComponent } from "./general-configuration/general-configuration.component";
+import { SecurityAuthenticationConfigurationComponent } from "./security-configuration/authentication-configuration/authentication-configuration.component";
+import { RouterModule } from "@angular/router";
 
 @NgModule({
   imports: [
@@ -75,6 +74,42 @@ import {
     CoreUiModule,
     ReactiveFormsModule,
     PlatformServicesModule,
+    RouterModule.forChild([
+      {
+        path: 'configuration',
+        children: [
+          {
+            path: '',
+            redirectTo: 'general',
+            pathMatch: 'full'
+          },
+          {
+            path: 'general',
+            component: GeneralConfigurationComponent
+          },
+          {
+            path: 'datalake',
+            component: DatalakeConfigurationComponent
+          },
+          {
+            path: 'email',
+            component: EmailConfigurationComponent
+          },
+          {
+            path: 'messaging',
+            component: MessagingConfigurationComponent
+          },
+          {
+            path: 'pipelineelement',
+            component: PipelineElementConfigurationComponent
+          },
+          {
+            path: 'security',
+            component: SecurityConfigurationComponent
+          }
+        ]
+      }
+    ]),
   ],
   declarations: [
     ConfigurationComponent,
@@ -98,9 +133,6 @@ import {
     MessagingConfigurationComponent,
     DatalakeConfigurationComponent,
   ],
-  providers: [
-    ConfigurationService,
-  ]
+  providers: [ConfigurationService],
 })
-export class ConfigurationModule {
-}
+export class ConfigurationModule {}
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 bbc29d5ae..bc576c09b 100644
--- a/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
+++ b/ui/src/app/configuration/datalake-configuration/datalake-configuration.component.html
@@ -16,95 +16,82 @@
   ~
   -->
 
-<div fxLayout="row" class="page-container-padding">
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
-        <sp-split-section title="Data Lake Settings"
-                          subtitle="Truncate and delete persisted data streams">
-            <div fxFlex="100" fxLayout="column">
-                <div class="subsection-title">Existing data lake indices</div>
-                <table
-                        fxFlex="100"
-                        mat-table
-                        data-cy="datalake-settings"
-                        [dataSource]="dataSource"
-                        style="width: 100%;"
-                        matSort>
 
-                    <ng-container matColumnDef="name">
-                        <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>
-                        <td mat-cell *matCellDef="let configurationEntry">
-                            <h4 style="margin-bottom:0px;">{{configurationEntry.name}}</h4>
-                        </td>
-                    </ng-container>
+<sp-configuration-component [activeLink]="'datalake'">
+    <div fxLayout="row" class="page-container-padding">
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="Data Lake Settings" subtitle="Truncate and delete persisted data streams">
+                <div fxFlex="100" fxLayout="column">
+                    <div class="subsection-title">Existing data lake indices</div>
+                    <table fxFlex="100" mat-table data-cy="datalake-settings" [dataSource]="dataSource"
+                        style="width: 100%;" matSort>
 
-                    <ng-container matColumnDef="pipeline">
-                        <th mat-header-cell mat-sort-header *matHeaderCellDef>Related Pipeline</th>
-                        <td mat-cell *matCellDef="let configurationEntry">
-                            {{configurationEntry.pipelines}}
-                        </td>
-                    </ng-container>
+                        <ng-container matColumnDef="name">
+                            <th mat-header-cell mat-sort-header *matHeaderCellDef>Name</th>
+                            <td mat-cell *matCellDef="let configurationEntry">
+                                <h4 style="margin-bottom:0px;">{{configurationEntry.name}}</h4>
+                            </td>
+                        </ng-container>
 
-                    <ng-container matColumnDef="events">
-                        <th mat-header-cell mat-sort-header *matHeaderCellDef># Events</th>
-                        <td
-                                mat-cell
-                                data-cy="datalake-number-of-events"
-                                *matCellDef="let configurationEntry">
-                            {{configurationEntry.events | number}}
-                        </td>
-                    </ng-container>
+                        <ng-container matColumnDef="pipeline">
+                            <th mat-header-cell mat-sort-header *matHeaderCellDef>Related Pipeline</th>
+                            <td mat-cell *matCellDef="let configurationEntry">
+                                {{configurationEntry.pipelines}}
+                            </td>
+                        </ng-container>
 
-                    <ng-container matColumnDef="truncate">
-                        <th mat-header-cell *matHeaderCellDef>Truncate</th>
-                        <td mat-cell *matCellDef="let configurationEntry">
-                            <div fxLayout="row">
-                            <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
-                                    <button color="accent"
-                                            mat-button
-                                            mat-icon-button
-                                            matTooltip="Truncate all data from index"
-                                            matTooltipPosition="above"
+                        <ng-container matColumnDef="events">
+                            <th mat-header-cell mat-sort-header *matHeaderCellDef># Events</th>
+                            <td mat-cell data-cy="datalake-number-of-events" *matCellDef="let configurationEntry">
+                                {{configurationEntry.events | number}}
+                            </td>
+                        </ng-container>
+
+                        <ng-container matColumnDef="truncate">
+                            <th mat-header-cell *matHeaderCellDef>Truncate</th>
+                            <td mat-cell *matCellDef="let configurationEntry">
+                                <div fxLayout="row">
+                                    <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
+                                        <button color="accent" mat-button mat-icon-button
+                                            matTooltip="Truncate all data from index" matTooltipPosition="above"
                                             data-cy="datalake-truncate-btn"
                                             (click)="cleanDatalakeIndex(configurationEntry.name)">
-                                        <i class="material-icons">local_fire_department</i>
-                                    </button>
-                                </span>
-                            </div>
-                        </td>
-                    </ng-container>
+                                            <i class="material-icons">local_fire_department</i>
+                                        </button>
+                                    </span>
+                                </div>
+                            </td>
+                        </ng-container>
 
-                    <ng-container matColumnDef="remove">
-                        <th mat-header-cell *matHeaderCellDef>Remove</th>
-                        <td mat-cell *matCellDef="let configurationEntry">
-                            <div fxLayout="row">
-                            <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
-                                    <button color="accent"
-                                            mat-button
-                                            mat-icon-button
-                                            matTooltip="Remove index from database"
-                                            data-cy="datalake-delete-btn"
-                                            matTooltipPosition="above"
-                                            [disabled]="!configurationEntry.remove"
+                        <ng-container matColumnDef="remove">
+                            <th mat-header-cell *matHeaderCellDef>Remove</th>
+                            <td mat-cell *matCellDef="let configurationEntry">
+                                <div fxLayout="row">
+                                    <span fxFlex fxFlexOrder="3" fxLayout="row" fxLayoutAlign="center center">
+                                        <button color="accent" mat-button mat-icon-button
+                                            matTooltip="Remove index from database" data-cy="datalake-delete-btn"
+                                            matTooltipPosition="above" [disabled]="!configurationEntry.remove"
                                             (click)="deleteDatalakeIndex(configurationEntry.name)">
-                                        <i class="material-icons">delete</i>
-                                    </button>
-                                </span>
-                            </div>
-                        </td>
-                    </ng-container>
+                                            <i class="material-icons">delete</i>
+                                        </button>
+                                    </span>
+                                </div>
+                            </td>
+                        </ng-container>
 
-                    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-                    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
+                        <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+                        <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
 
-                </table>
-            </div>
-            <div fxFlex="100" fxLayoutAlign="end end">
-                <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" [pageSize]="20"></mat-paginator>
-            </div>
-            <div fxFlex="100" fxLayout="column" fxLayoutAlign="center center" *ngIf="availableMeasurements.length == 0">
-                <h5>(no stored measurements)</h5>
-            </div>
-        </sp-split-section>
+                    </table>
+                </div>
+                <div fxFlex="100" fxLayoutAlign="end end">
+                    <mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" [pageSize]="20"></mat-paginator>
+                </div>
+                <div fxFlex="100" fxLayout="column" fxLayoutAlign="center center"
+                    *ngIf="availableMeasurements.length == 0">
+                    <h5>(no stored measurements)</h5>
+                </div>
+            </sp-split-section>
+        </div>
     </div>
-</div>
-
+</sp-configuration-component>
\ No newline at end of file
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 f1ddd7e51..3eff4b18f 100644
--- a/ui/src/app/configuration/email-configuration/email-configuration.component.html
+++ b/ui/src/app/configuration/email-configuration/email-configuration.component.html
@@ -16,114 +16,101 @@
   ~
   -->
 
-<div fxLayout="column" class="page-container-padding">
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" *ngIf="formReady">
-        <sp-split-section title="Mail Settings"
-                          subtitle="Settings to connect to a mail server">
-            <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
-                <div class="subsection-title">Mail Server</div>
-                <mat-form-field color="accent">
-                    <mat-label>SMTP Host</mat-label>
-                    <input formControlName="smtpServerHost" fxFlex
-                           matInput
-                           required>
-                </mat-form-field>
-                <mat-form-field color="accent">
-                    <mat-label>SMTP Port</mat-label>
-                    <input type="number" formControlName="smtpServerPort" fxFlex
-                           matInput
-                           required>
-                </mat-form-field>
-                <div class="subsection-title">Transport</div>
-                <mat-radio-group fxLayout="column" formControlName="transport">
-                    <mat-radio-button value="SMTP" class="m-5">SMTP</mat-radio-button>
-                    <mat-radio-button value="SMTPS" class="m-5">SMTPS</mat-radio-button>
-                    <mat-radio-button value="SMTP_TLS" class="m-5">TLS</mat-radio-button>
-                </mat-radio-group>
-                <div class="subsection-title mt-20">Authentication</div>
-                <mat-checkbox formControlName="usesAuthentication">SMTP server requires authentication</mat-checkbox>
-                <mat-form-field color="accent" *ngIf="mailConfig.usesAuthentication">
-                    <mat-label>SMTP Username</mat-label>
-                    <input formControlName="smtpUsername" fxFlex
-                           matInput>
-                </mat-form-field>
-                <mat-form-field color="accent" *ngIf="mailConfig.usesAuthentication">
-                    <mat-label>SMTP Password</mat-label>
-                    <input formControlName="smtpPassword" fxFlex type="password"
-                           matInput>
-                </mat-form-field>
-                <div class="subsection-title mt-20">Proxy</div>
-                <mat-checkbox formControlName="usesProxy">Uses proxy</mat-checkbox>
-                <mat-form-field color="accent" *ngIf="mailConfig.usesProxy">
-                    <mat-label>Proxy Host</mat-label>
-                    <input formControlName="proxyHost" fxFlex
-                           matInput>
-                </mat-form-field>
-                <mat-form-field color="accent" *ngIf="mailConfig.usesProxy">
-                    <mat-label>Proxy Port</mat-label>
-                    <input formControlName="proxyPort" fxFlex
-                           matInput>
-                </mat-form-field>
-                <mat-checkbox formControlName="usesProxyAuthentication" *ngIf="mailConfig.usesProxy">
-                    Proxy requires authentication
-                </mat-checkbox>
-                <mat-form-field color="accent" *ngIf="mailConfig.usesProxy && mailConfig.usesProxyAuthentication">
-                    <mat-label>Proxy Username</mat-label>
-                    <input formControlName="proxyUsername" fxFlex
-                           matInput>
-                </mat-form-field>
-                <mat-form-field color="accent" *ngIf="mailConfig.usesProxy && mailConfig.usesProxyAuthentication">
-                    <mat-label>Proxy Password</mat-label>
-                    <input formControlName="proxyPassword" fxFlex type="password"
-                           matInput>
-                </mat-form-field>
-                <div class="subsection-title mt-20">Sender</div>
-                <mat-form-field color="accent">
-                    <mat-label>Sender Email Address</mat-label>
-                    <input formControlName="senderAddress" fxFlex
-                           matInput
-                           required>
-                </mat-form-field>
-                <mat-form-field color="accent">
-                    <mat-label>Sender Name</mat-label>
-                    <input formControlName="senderName" fxFlex
-                           matInput>
-                </mat-form-field>
-                <mat-form-field color="accent">
-                    <mat-label>Recipient for test mail</mat-label>
-                    <input formControlName="defaultRecipient" fxFlex
-                           matInput>
-                </mat-form-field>
-                <div fxLayout="row">
-                <button mat-button mat-raised-button color="accent" (click)="save()" style="margin-right:10px;"
-                        [disabled]="!parentForm.valid"
-                        data-cy="sp-element-email-config-save">
-                    <i class="material-icons">save</i><span>&nbsp;Save</span>
-                </button>
-                <button mat-button mat-raised-button class="mat-basic" (click)="sendTestMail()" style="margin-right:10px;"
-                        [disabled]="!parentForm.valid || sendingTestMailInProgress"
-                        data-cy="sp-element-email-config-test">
-                    <span>Send Test Mail</span>
-                </button>
-                </div>
-                <div fxLayout="column" *ngIf="attemptSendingTestMail">
-                    <div fxLayout="row" *ngIf="sendingTestMailInProgress">
-                        <mat-progress-spinner diameter="10"></mat-progress-spinner>
-                        <h5>Trying to send test mail...</h5>
-                    </div>
+<sp-configuration-component [activeLink]="'email'">
+    <div fxLayout="column" class="page-container-padding">
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" *ngIf="formReady">
+            <sp-split-section title="Mail Settings" subtitle="Settings to connect to a mail server">
+                <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
+                    <div class="subsection-title">Mail Server</div>
+                    <mat-form-field color="accent">
+                        <mat-label>SMTP Host</mat-label>
+                        <input formControlName="smtpServerHost" fxFlex matInput required>
+                    </mat-form-field>
+                    <mat-form-field color="accent">
+                        <mat-label>SMTP Port</mat-label>
+                        <input type="number" formControlName="smtpServerPort" fxFlex matInput required>
+                    </mat-form-field>
+                    <div class="subsection-title">Transport</div>
+                    <mat-radio-group fxLayout="column" formControlName="transport">
+                        <mat-radio-button value="SMTP" class="m-5">SMTP</mat-radio-button>
+                        <mat-radio-button value="SMTPS" class="m-5">SMTPS</mat-radio-button>
+                        <mat-radio-button value="SMTP_TLS" class="m-5">TLS</mat-radio-button>
+                    </mat-radio-group>
+                    <div class="subsection-title mt-20">Authentication</div>
+                    <mat-checkbox formControlName="usesAuthentication">SMTP server requires authentication
+                    </mat-checkbox>
+                    <mat-form-field color="accent" *ngIf="mailConfig.usesAuthentication">
+                        <mat-label>SMTP Username</mat-label>
+                        <input formControlName="smtpUsername" fxFlex matInput>
+                    </mat-form-field>
+                    <mat-form-field color="accent" *ngIf="mailConfig.usesAuthentication">
+                        <mat-label>SMTP Password</mat-label>
+                        <input formControlName="smtpPassword" fxFlex type="password" matInput>
+                    </mat-form-field>
+                    <div class="subsection-title mt-20">Proxy</div>
+                    <mat-checkbox formControlName="usesProxy">Uses proxy</mat-checkbox>
+                    <mat-form-field color="accent" *ngIf="mailConfig.usesProxy">
+                        <mat-label>Proxy Host</mat-label>
+                        <input formControlName="proxyHost" fxFlex matInput>
+                    </mat-form-field>
+                    <mat-form-field color="accent" *ngIf="mailConfig.usesProxy">
+                        <mat-label>Proxy Port</mat-label>
+                        <input formControlName="proxyPort" fxFlex matInput>
+                    </mat-form-field>
+                    <mat-checkbox formControlName="usesProxyAuthentication" *ngIf="mailConfig.usesProxy">
+                        Proxy requires authentication
+                    </mat-checkbox>
+                    <mat-form-field color="accent" *ngIf="mailConfig.usesProxy && mailConfig.usesProxyAuthentication">
+                        <mat-label>Proxy Username</mat-label>
+                        <input formControlName="proxyUsername" fxFlex matInput>
+                    </mat-form-field>
+                    <mat-form-field color="accent" *ngIf="mailConfig.usesProxy && mailConfig.usesProxyAuthentication">
+                        <mat-label>Proxy Password</mat-label>
+                        <input formControlName="proxyPassword" fxFlex type="password" matInput>
+                    </mat-form-field>
+                    <div class="subsection-title mt-20">Sender</div>
+                    <mat-form-field color="accent">
+                        <mat-label>Sender Email Address</mat-label>
+                        <input formControlName="senderAddress" fxFlex matInput required>
+                    </mat-form-field>
+                    <mat-form-field color="accent">
+                        <mat-label>Sender Name</mat-label>
+                        <input formControlName="senderName" fxFlex matInput>
+                    </mat-form-field>
+                    <mat-form-field color="accent">
+                        <mat-label>Recipient for test mail</mat-label>
+                        <input formControlName="defaultRecipient" fxFlex matInput>
+                    </mat-form-field>
                     <div fxLayout="row">
-                        <h5 *ngIf="!sendingTestMailInProgress && sendingTestMailSuccess">Success - please check your mail inbox.</h5>
-                        <div fxLayout="column" *ngIf="!sendingTestMailInProgress && !sendingTestMailSuccess">
-                            Failure
-                            <h5>{{sendingEmailErrorMessage}}</h5>
+                        <button mat-button mat-raised-button color="accent" (click)="save()" style="margin-right:10px;"
+                            [disabled]="!parentForm.valid" data-cy="sp-element-email-config-save">
+                            <i class="material-icons">save</i><span>&nbsp;Save</span>
+                        </button>
+                        <button mat-button mat-raised-button class="mat-basic" (click)="sendTestMail()"
+                            style="margin-right:10px;" [disabled]="!parentForm.valid || sendingTestMailInProgress"
+                            data-cy="sp-element-email-config-test">
+                            <span>Send Test Mail</span>
+                        </button>
+                    </div>
+                    <div fxLayout="column" *ngIf="attemptSendingTestMail">
+                        <div fxLayout="row" *ngIf="sendingTestMailInProgress">
+                            <mat-progress-spinner diameter="10"></mat-progress-spinner>
+                            <h5>Trying to send test mail...</h5>
+                        </div>
+                        <div fxLayout="row">
+                            <h5 *ngIf="!sendingTestMailInProgress && sendingTestMailSuccess">Success - please check your
+                                mail inbox.</h5>
+                            <div fxLayout="column" *ngIf="!sendingTestMailInProgress && !sendingTestMailSuccess">
+                                Failure
+                                <h5>{{sendingEmailErrorMessage}}</h5>
+                            </div>
                         </div>
                     </div>
-                </div>
-            </form>
-        </sp-split-section>
-    </div>
-    <mat-divider></mat-divider>
-
+                </form>
+            </sp-split-section>
+        </div>
+        <mat-divider></mat-divider>
 
-</div>
 
+    </div>
+</sp-configuration-component>
\ No newline at end of file
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 2df113431..e072b9840 100644
--- a/ui/src/app/configuration/general-configuration/general-configuration.component.html
+++ b/ui/src/app/configuration/general-configuration/general-configuration.component.html
@@ -15,84 +15,78 @@
   ~ limitations under the License.
   ~
   -->
-
-<div fxLayout="column" class="page-container-padding">
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" *ngIf="formReady">
-        <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
-            <div class="warning mb-10" *ngIf="!generalConfig.configured">These are default values - to use features
-                such as email you need to store these values once.
-            </div>
-            <sp-split-section title="Basic"
-                              subtitle="Basic settings">
-                <div class="subsection-title">App Name</div>
-                <mat-form-field color="accent" class="ml-10">
-                    <mat-label>App Name</mat-label>
-                    <input formControlName="appName" fxFlex
-                           matInput
-                           required>
-                </mat-form-field>
-                <div class="subsection-title">Host and Port</div>
-                <div fxLayout="column" fxFlex="100">
-                    <div fxLayout="row">
-                        <div>
-                            <mat-button-toggle-group name="protocol" aria-label="Protocol" formControlName="protocol">
-                                <mat-button-toggle value="http">http</mat-button-toggle>
-                                <mat-button-toggle value="https">https</mat-button-toggle>
-                            </mat-button-toggle-group>
+<sp-configuration-component [activeLink]="'general'">
+    <div fxLayout="column" class="page-container-padding">
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" *ngIf="formReady">
+            <form [formGroup]="parentForm" fxFlex="100" fxLayout="column">
+                <div class="warning mb-10" *ngIf="!generalConfig.configured">These are default values - to use features
+                    such as email you need to store these values once.
+                </div>
+                <sp-split-section title="Basic" subtitle="Basic settings">
+                    <div class="subsection-title">App Name</div>
+                    <mat-form-field color="accent" class="ml-10">
+                        <mat-label>App Name</mat-label>
+                        <input formControlName="appName" fxFlex matInput required>
+                    </mat-form-field>
+                    <div class="subsection-title">Host and Port</div>
+                    <div fxLayout="column" fxFlex="100">
+                        <div fxLayout="row">
+                            <div>
+                                <mat-button-toggle-group name="protocol" aria-label="Protocol"
+                                    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">
+                                <mat-label>Host</mat-label>
+                                <input formControlName="hostname" fxFlex matInput required>
+                            </mat-form-field>
+                            <mat-form-field color="accent" class="ml-10">
+                                <mat-label>Port</mat-label>
+                                <input formControlName="port" fxFlex matInput type="number" required>
+                            </mat-form-field>
                         </div>
-                        <mat-form-field color="accent" class="ml-10">
-                            <mat-label>Host</mat-label>
-                            <input formControlName="hostname" fxFlex
-                                   matInput
-                                   required>
-                        </mat-form-field>
-                        <mat-form-field color="accent" class="ml-10">
-                            <mat-label>Port</mat-label>
-                            <input formControlName="port" fxFlex
-                                   matInput
-                                   type="number"
-                                   required>
-                        </mat-form-field>
                     </div>
-                </div>
-                <div class="mt-10">
-                    <button mat-button mat-raised-button color="accent" (click)="updateConfig()"
-                            style="margin-right:10px;"
-                            [disabled]="!parentForm.valid"
+                    <div class="mt-10">
+                        <button mat-button mat-raised-button color="accent" (click)="updateConfig()"
+                            style="margin-right:10px;" [disabled]="!parentForm.valid"
                             data-cy="sp-element-general-config-save">
-                        <i class="material-icons">save</i><span>&nbsp;Save</span>
-                    </button>
-                </div>
-            </sp-split-section>
-            <mat-divider></mat-divider>
-            <sp-split-section title="Registration"
-                              subtitle="Registration process">
-                <div class="warning mb-10" *ngIf="!generalConfig.configured || !mailConfig.emailConfigured">Requires valid
-                    mail server settings and basic host settings.
-                </div>
-                <mat-checkbox [disabled]="!generalConfig.configured || !mailConfig.emailConfigured"
-                              formControlName="allowSelfRegistration">Allow self-registration
-                </mat-checkbox>
-                <div *ngIf="generalConfig.allowSelfRegistration" class="mt-10 mb-10">
-                    <h5>Default roles for new users</h5>
-                    <mat-select formControlName="defaultUserRoles" [multiple]="true">
-                        <mat-option *ngFor="let role of availableRoles" [value]="role.role">{{role.roleTitle}}</mat-option>
-                    </mat-select>
-                </div>
-                <mat-checkbox [disabled]="!generalConfig.configured || !mailConfig.emailConfigured"
-                              formControlName="allowPasswordRecovery">Allow self-service password recovery
-                </mat-checkbox>
+                            <i class="material-icons">save</i><span>&nbsp;Save</span>
+                        </button>
+                    </div>
+                </sp-split-section>
+                <mat-divider></mat-divider>
+                <sp-split-section title="Registration" subtitle="Registration process">
+                    <div class="warning mb-10" *ngIf="!generalConfig.configured || !mailConfig.emailConfigured">Requires
+                        valid
+                        mail server settings and basic host settings.
+                    </div>
+                    <mat-checkbox [disabled]="!generalConfig.configured || !mailConfig.emailConfigured"
+                        formControlName="allowSelfRegistration">Allow self-registration
+                    </mat-checkbox>
+                    <div *ngIf="generalConfig.allowSelfRegistration" class="mt-10 mb-10">
+                        <h5>Default roles for new users</h5>
+                        <mat-select formControlName="defaultUserRoles" [multiple]="true">
+                            <mat-option *ngFor="let role of availableRoles" [value]="role.role">{{role.roleTitle}}
+                            </mat-option>
+                        </mat-select>
+                    </div>
+                    <mat-checkbox [disabled]="!generalConfig.configured || !mailConfig.emailConfigured"
+                        formControlName="allowPasswordRecovery">Allow self-service password recovery
+                    </mat-checkbox>
 
-                <div class="mt-10">
-                    <button mat-button mat-raised-button color="accent" (click)="updateConfig()"
+                    <div class="mt-10">
+                        <button mat-button mat-raised-button color="accent" (click)="updateConfig()"
                             style="margin-right:10px;"
                             [disabled]="!generalConfig.configured || !mailConfig.emailConfigured"
                             data-cy="sp-element-general-registration-config-save">
-                        <i class="material-icons">save</i><span>&nbsp;Save</span>
-                    </button>
-                </div>
-            </sp-split-section>
-        </form>
-    </div>
+                            <i class="material-icons">save</i><span>&nbsp;Save</span>
+                        </button>
+                    </div>
+                </sp-split-section>
+            </form>
+        </div>
 
-</div>
+    </div>
+</sp-configuration-component>
\ No newline at end of file
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 61d96e35b..57f31bd8d 100644
--- a/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
+++ b/ui/src/app/configuration/messaging-configuration/messaging-configuration.component.html
@@ -16,78 +16,71 @@
   ~
   -->
 
-<div fxLayout="column" class="page-container-padding">
-    <sp-split-section title="Kafka Settings"
-                      subtitle="Manage Kafka settings for pipeline communication">
-        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="page-container-padding-inner">
-            <form (ngSubmit)="updateMessagingSettings()" class="form-width" fxFlex="100" fxLayout="column"
-                  *ngIf="loadingCompleted">
-                <mat-form-field class="form-field" fxFlex="100">
-                    <input matInput [(ngModel)]="messagingSettings.batchSize"
-                           [placeholder]="'Batch Size'" type="text"
-                           [ngModelOptions]="{standalone: true}">
-                </mat-form-field>
-                <mat-form-field class="form-field" fxFlex="100">
-                    <input matInput [(ngModel)]="messagingSettings.messageMaxBytes"
-                           [placeholder]="'Message Max Bytes'" type="text"
-                           [ngModelOptions]="{standalone: true}">
-                </mat-form-field>
-                <mat-form-field class="form-field" fxFlex="100">
-                    <input matInput [(ngModel)]="messagingSettings.acks"
-                           [placeholder]="'Acks'" type="text"
-                           [ngModelOptions]="{standalone: true}">
-                </mat-form-field>
-                <mat-form-field class="form-field" fxFlex="100">
-                    <input matInput [(ngModel)]="messagingSettings.lingerMs"
-                           [placeholder]="'Linger MS'" type="text"
-                           [ngModelOptions]="{standalone: true}">
-                </mat-form-field>
-                <div fxLayoutAlign="start center" class="mt-10">
-                    <button mat-raised-button color="accent" type="submit"
+<sp-configuration-component [activeLink]="'messaging'">
+    <div fxLayout="column" class="page-container-padding">
+        <sp-split-section title="Kafka Settings" subtitle="Manage Kafka settings for pipeline communication">
+            <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="page-container-padding-inner">
+                <form (ngSubmit)="updateMessagingSettings()" class="form-width" fxFlex="100" fxLayout="column"
+                    *ngIf="loadingCompleted">
+                    <mat-form-field class="form-field" fxFlex="100">
+                        <input matInput [(ngModel)]="messagingSettings.batchSize" [placeholder]="'Batch Size'"
+                            type="text" [ngModelOptions]="{standalone: true}">
+                    </mat-form-field>
+                    <mat-form-field class="form-field" fxFlex="100">
+                        <input matInput [(ngModel)]="messagingSettings.messageMaxBytes"
+                            [placeholder]="'Message Max Bytes'" type="text" [ngModelOptions]="{standalone: true}">
+                    </mat-form-field>
+                    <mat-form-field class="form-field" fxFlex="100">
+                        <input matInput [(ngModel)]="messagingSettings.acks" [placeholder]="'Acks'" type="text"
+                            [ngModelOptions]="{standalone: true}">
+                    </mat-form-field>
+                    <mat-form-field class="form-field" fxFlex="100">
+                        <input matInput [(ngModel)]="messagingSettings.lingerMs" [placeholder]="'Linger MS'" type="text"
+                            [ngModelOptions]="{standalone: true}">
+                    </mat-form-field>
+                    <div fxLayoutAlign="start center" class="mt-10">
+                        <button mat-raised-button color="accent" type="submit"
                             class="md-raised md-primary submit-button">Update
-                    </button>
-                </div>
+                        </button>
+                    </div>
 
-            </form>
-        </div>
-    </sp-split-section>
-    <mat-divider></mat-divider>
+                </form>
+            </div>
+        </sp-split-section>
+        <mat-divider></mat-divider>
 
-    <sp-split-section title="Message Formats"
-                      subtitle="Manage the priority of message formats used">
-        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="page-container-padding-inner">
-            <div cdkDropList class="data-format-list" (cdkDropListDropped)="drop($event)"
-                 *ngIf="loadingCompleted">
-                <div class="data-format-box" *ngFor="let format of messagingSettings.prioritizedFormats"
-                     cdkDrag>
-                    {{format}}
+        <sp-split-section title="Message Formats" subtitle="Manage the priority of message formats used">
+            <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="page-container-padding-inner">
+                <div cdkDropList class="data-format-list" (cdkDropListDropped)="drop($event)" *ngIf="loadingCompleted">
+                    <div class="data-format-box" *ngFor="let format of messagingSettings.prioritizedFormats" cdkDrag>
+                        {{format}}
+                    </div>
+                </div>
+                <div fxLayoutAlign="start center" class="mt-10">
+                    <button mat-raised-button color="accent" type="submit" class="md-raised md-primary submit-button"
+                        (click)="updateMessagingSettings()">Update
+                    </button>
                 </div>
             </div>
-            <div fxLayoutAlign="start center" class="mt-10">
-                <button mat-raised-button color="accent" type="submit"
-                        class="md-raised md-primary submit-button" (click)="updateMessagingSettings()">Update
-                </button>
-            </div>
-        </div>
-    </sp-split-section>
+        </sp-split-section>
 
-    <mat-divider></mat-divider>
+        <mat-divider></mat-divider>
 
-    <sp-split-section title="Protocols"
-                      subtitle="Manage the priority of protocols used">
-        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="page-container-padding-inner">
-            <div cdkDropList class="data-format-list" (cdkDropListDropped)="dropProtocol($event)"
-                 *ngIf="loadingCompleted">
-                <div class="data-format-box" *ngFor="let protocol of messagingSettings.prioritizedProtocols"
-                     cdkDrag>
-                    {{protocol}}
+        <sp-split-section title="Protocols" subtitle="Manage the priority of protocols used">
+            <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start" class="page-container-padding-inner">
+                <div cdkDropList class="data-format-list" (cdkDropListDropped)="dropProtocol($event)"
+                    *ngIf="loadingCompleted">
+                    <div class="data-format-box" *ngFor="let protocol of messagingSettings.prioritizedProtocols"
+                        cdkDrag>
+                        {{protocol}}
+                    </div>
+                </div>
+                <div fxLayoutAlign="start center" class="mt-10">
+                    <button mat-raised-button color="accent" type="submit" class="md-raised md-primary submit-button"
+                        (click)="updateMessagingSettings()">Update
+                    </button>
                 </div>
             </div>
-            <div fxLayoutAlign="start center" class="mt-10">
-                <button mat-raised-button color="accent" type="submit"
-                        class="md-raised md-primary submit-button" (click)="updateMessagingSettings()">Update
-                </button>
-            </div>
-        </div>
-    </sp-split-section>
-</div>
+        </sp-split-section>
+    </div>
+</sp-configuration-component>
diff --git a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html
index 339fe0a3d..31c942a73 100644
--- a/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html
+++ b/ui/src/app/configuration/pipeline-element-configuration/pipeline-element-configuration.component.html
@@ -16,60 +16,63 @@
   ~
   -->
 
-<div fxLayout="row" class="page-container-padding">
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
-        <sp-split-section title="Pipeline Element Configuration"
-                          subtitle="Configure basic settings of core and extensions services">
-            <table fxFlex="100" mat-table [dataSource]="dataSource" multiTemplateDataRows>
+<sp-configuration-component [activeLink]="'pipelineelement'">
+    <div fxLayout="row" class="page-container-padding">
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="Pipeline Element Configuration"
+                subtitle="Configure basic settings of core and extensions services">
+                <table fxFlex="100" mat-table [dataSource]="dataSource" multiTemplateDataRows>
 
-                <ng-container matColumnDef="status">
-                    <th fxFlex="30" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Status</th>
-                    <td fxFlex="30" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
+                    <ng-container matColumnDef="status">
+                        <th fxFlex="30" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Status</th>
+                        <td fxFlex="30" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
                             <span *ngIf="element.meta.status === 'passing'" fxLayoutAlign="center center">
                                 <mat-icon class="service-icon-passing">lens</mat-icon>
                             </span>
-                        <span *ngIf="element.meta.status === 'critical'" fxLayoutAlign="center center">
+                            <span *ngIf="element.meta.status === 'critical'" fxLayoutAlign="center center">
                                 <mat-icon class="service-icon-critical">lens</mat-icon>
                             </span>
-                    </td>
-                </ng-container>
+                        </td>
+                    </ng-container>
 
-                <ng-container matColumnDef="name">
-                    <th fxFlex="40" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Extensions Service Group
-                    </th>
-                    <td fxFlex="40" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
-                        {{element.name}}
-                    </td>
-                </ng-container>
+                    <ng-container matColumnDef="name">
+                        <th fxFlex="40" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Extensions
+                            Service Group
+                        </th>
+                        <td fxFlex="40" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
+                            {{element.name}}
+                        </td>
+                    </ng-container>
 
-                <ng-container matColumnDef="action">
-                    <th fxFlex="30" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Action</th>
-                    <td fxFlex="30" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
-                        <button mat-button mat-raised-button color="accent" (click)="expand(element)">
-                            Edit
-                        </button>
-                    </td>
-                </ng-container>
+                    <ng-container matColumnDef="action">
+                        <th fxFlex="30" fxLayoutAlign="start center" mat-header-cell *matHeaderCellDef> Action</th>
+                        <td fxFlex="30" fxLayoutAlign="start center" mat-cell *matCellDef="let element">
+                            <button mat-button mat-raised-button color="accent" (click)="expand(element)">
+                                Edit
+                            </button>
+                        </td>
+                    </ng-container>
 
-                <ng-container matColumnDef="expandedDetail">
-                    <td mat-cell *matCellDef="let element" [attr.colspan]="displayedColumns.length">
-                        <div class="consul-configuration-detail"
-                             [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
-                            <div fxFlex="100">
-                                <consul-configs [consulService]="element"
-                                                (updateConsulService)="updateConsulService($event)"></consul-configs>
+                    <ng-container matColumnDef="expandedDetail">
+                        <td mat-cell *matCellDef="let element" [attr.colspan]="displayedColumns.length">
+                            <div class="consul-configuration-detail"
+                                [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'">
+                                <div fxFlex="100">
+                                    <consul-configs [consulService]="element"
+                                        (updateConsulService)="updateConsulService($event)"></consul-configs>
+                                </div>
                             </div>
-                        </div>
-                    </td>
-                </ng-container>
+                        </td>
+                    </ng-container>
 
-                <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-                <tr mat-row *matRowDef="let element; columns: displayedColumns;"
-                    class="consul-configuration-row"
-                    [class.consul-configuration-row-expanded]="expandedElement === element">
-                </tr>
-                <tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="consul-configuration-detail-row"></tr>
-            </table>
-        </sp-split-section>
+                    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+                    <tr mat-row *matRowDef="let element; columns: displayedColumns;" class="consul-configuration-row"
+                        [class.consul-configuration-row-expanded]="expandedElement === element">
+                    </tr>
+                    <tr mat-row *matRowDef="let row; columns: ['expandedDetail']"
+                        class="consul-configuration-detail-row"></tr>
+                </table>
+            </sp-split-section>
+        </div>
     </div>
-</div>
+</sp-configuration-component>
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 3afffc9b6..f5a8acb83 100644
--- a/ui/src/app/configuration/security-configuration/security-configuration.component.html
+++ b/ui/src/app/configuration/security-configuration/security-configuration.component.html
@@ -16,36 +16,34 @@
   ~
   -->
 
-<div fxLayout="column" class="page-container-padding">
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
-        <sp-split-section title="User Accounts"
-                          subtitle="Add and edit user accounts">
-            <div class="subsection-title">Existing user accounts</div>
-            <sp-security-user-config></sp-security-user-config>
-        </sp-split-section>
+<sp-configuration-component [activeLink]="'security'">
+    <div fxLayout="column" class="page-container-padding">
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="User Accounts" subtitle="Add and edit user accounts">
+                <div class="subsection-title">Existing user accounts</div>
+                <sp-security-user-config></sp-security-user-config>
+            </sp-split-section>
+        </div>
+        <mat-divider></mat-divider>
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="Service Accounts" subtitle="Add and edit service accounts">
+                <div class="subsection-title">Existing service accounts</div>
+                <sp-security-service-config></sp-security-service-config>
+            </sp-split-section>
+        </div>
+        <mat-divider></mat-divider>
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="Groups" subtitle="Manage user groups">
+                <div class="subsection-title">Existing groups</div>
+                <sp-security-user-group-config></sp-security-user-group-config>
+            </sp-split-section>
+        </div>
+        <mat-divider></mat-divider>
+        <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
+            <sp-split-section title="Authentication" subtitle="Auth & token settings">
+                <div class="subsection-title">JWT Signature</div>
+                <sp-authentication-configuration></sp-authentication-configuration>
+            </sp-split-section>
+        </div>
     </div>
-    <mat-divider></mat-divider>
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
-        <sp-split-section title="Service Accounts"
-                          subtitle="Add and edit service accounts">
-            <div class="subsection-title">Existing service accounts</div>
-            <sp-security-service-config></sp-security-service-config>
-        </sp-split-section>
-    </div>
-    <mat-divider></mat-divider>
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
-        <sp-split-section title="Groups"
-                          subtitle="Manage user groups">
-            <div class="subsection-title">Existing groups</div>
-            <sp-security-user-group-config></sp-security-user-group-config>
-        </sp-split-section>
-    </div>
-    <mat-divider></mat-divider>
-    <div fxFlex="100" fxLayout="column" fxLayoutAlign="start start">
-        <sp-split-section title="Authentication"
-                          subtitle="Auth & token settings">
-            <div class="subsection-title">JWT Signature</div>
-            <sp-authentication-configuration></sp-authentication-configuration>
-        </sp-split-section>
-    </div>
-</div>
+</sp-configuration-component>