Index: /branches/amp_4_0/platform/config/syslog.conf
===================================================================
--- /branches/amp_4_0/platform/config/syslog.conf	(revision 2701)
+++ /branches/amp_4_0/platform/config/syslog.conf	(working copy)
@@ -49,7 +49,7 @@
       }
       grok {
         match => {
-          "syslog_message" => "^AN_WELF_LOG:id=%{WORD:log_id} time=\"%{TIMESTAMP_ISO8601:log_time}\" fw=%{IP:virtual_ip} pri=%{POSINT:priority} proto=%{WORD:protocol} src=%{IP:src_ip} dstname=%{IP:destination_name} arg=%{URIPATH:arg} op=%{WORD:operation} agent=\"%{DATA:user_agent}\" result=%{INT:http_result_code} sent=%{INT:bytes_sent} duration=%{NUMBER:duration_seconds} msg=\"%{GREEDYDATA:message_detail_raw}\""
+          "syslog_message" => "^AN_WELF_LOG:id=%{WORD:log_id} time=\"%{TIMESTAMP_ISO8601:log_time}\" fw=%{IP:virtual_ip} pri=%{POSINT:priority} proto=%{WORD:protocol} src=%{IP:src_ip} dstname=%{IP:destination_name} arg=%{URIPATH:arg} op=%{WORD:http_method} agent=\"%{DATA:user_agent}\" result=%{INT:http_status_code} sent=%{INT:bytes_sent} duration=%{NUMBER:duration} msg=\"%{GREEDYDATA:message_detail_raw}\""
         }
         tag_on_failure => ["_grokparsefailure_an_welf_log_rfc5424"]
         add_tag => ["an_welf_log_rfc5424_subparsed"]
@@ -72,7 +72,7 @@
     if "_grokparsefailure_rfc5424" in [tags] {
       grok {
         match => {
-          "message" => "^<%{POSINT:syslog_pri}>%{POSINT:syslog_version} %{TIMESTAMP_ISO8601:syslog_timestamp} %{HOSTNAME:syslog_hostname} %{DATA:syslog_appname} %{DATA:syslog_procid} %{INT:event_id} - AN_WELF_LOG:id=%{WORD:log_id} time=\"%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day} %{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second}\" fw=%{IP:virtual_ip} pri=%{POSINT:priority} proto=%{WORD:protocol} src=%{IP:src_ip} dstname=%{IP:destination_name} arg=%{URIPATH:arg} op=%{WORD:operation} agent=\"%{DATA:user_agent}\" result=%{INT:http_result_code} sent=%{INT:bytes_sent} duration=%{NUMBER:duration_seconds} msg=\"%{GREEDYDATA:destination_data_raw}\""
+          "message" => "^<%{POSINT:syslog_pri}>%{POSINT:syslog_version} %{TIMESTAMP_ISO8601:syslog_timestamp} %{HOSTNAME:syslog_hostname} %{DATA:syslog_appname} %{DATA:syslog_procid} %{INT:event_id} - AN_WELF_LOG:id=%{WORD:log_id} time=\"%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day} %{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second}\" fw=%{IP:virtual_ip} pri=%{POSINT:priority} proto=%{WORD:protocol} src=%{IP:src_ip} dstname=%{IP:destination_name} arg=%{URIPATH:arg} op=%{WORD:http_method} agent=\"%{DATA:user_agent}\" result=%{INT:http_status_code} sent=%{INT:bytes_sent} duration=%{NUMBER:duration} msg=\"%{GREEDYDATA:destination_data_raw}\""
         }
         tag_on_failure => ["_grokparsefailure_an_welf_log"]
         add_tag => ["an_welf_log_attempt"]
@@ -92,7 +92,7 @@
     if "_grokparsefailure_rfc5424" in [tags] and "_grokparsefailure_an_welf_log" in [tags] {
       grok {
         match => {
-          "message" => "^AN_WELF_LOG:id=%{WORD:log_id} time=\"%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day} %{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second}\" fw=%{IP:virtual_ip} pri=%{POSINT:priority} proto=%{WORD:protocol} src=%{IP:src_ip} dstname=%{IP:destination_name} arg=%{URIPATH:arg} op=%{WORD:operation} agent=\"%{DATA:user_agent}\" result=%{INT:http_result_code} sent=%{INT:bytes_sent} duration=%{NUMBER:duration_seconds} msg=\"%{GREEDYDATA:message_detail_raw}\""
+          "message" => "^AN_WELF_LOG:id=%{WORD:log_id} time=\"%{YEAR:year}-%{MONTHNUM:month}-%{MONTHDAY:day} %{HOUR:hour}:%{MINUTE:minute}:%{SECOND:second}\" fw=%{IP:virtual_ip} pri=%{POSINT:priority} proto=%{WORD:protocol} src=%{IP:src_ip} dstname=%{IP:destination_name} arg=%{URIPATH:arg} op=%{WORD:http_method} agent=\"%{DATA:user_agent}\" result=%{INT:http_status_code} sent=%{INT:bytes_sent} duration=%{NUMBER:duration} msg=\"%{GREEDYDATA:message_detail_raw}\""
         }
         tag_on_failure => ["_grokparsefailure_an_welf_log_no_header"]
         add_tag => ["an_welf_log_no_header_attempt"]
@@ -141,7 +141,6 @@
           remove_field => ["syslog_month", "syslog_day", "syslog_year", "syslog_time", "syslog_content_kv"]
         }
 
-        # --- NEW ADDITIONS FOR CUSTOM/NON-STANDARD LOGS ---
         # Map fields from syslog_kv_data to common field names
         if [syslog_kv_data][fw] {
           mutate { add_field => { "virtual_ip" => "%{[syslog_kv_data][fw]}" } }
@@ -162,18 +161,10 @@
         if [syslog_kv_data][time] {
           date {
             match => ["syslog_kv_data.time", "YYYY-M-d HH:mm:ss"]
-            target => "log_message_timestamp" # Create a separate field for this specific timestamp
+            target => "log_message_timestamp"
             tag_on_failure => ["_kvtimeparsefailure"]
           }
-          # You might want to use this timestamp for @timestamp if it's more accurate
-          # date {
-          #   match => ["syslog_kv_data.time", "YYYY-M-d HH:mm:ss"]
-          #   target => "@timestamp"
-          #   timezone => "%{[syslog_kv_data][timezone]}" # This requires a valid IANA timezone name
-          #   tag_on_failure => ["_kvtimestampfailure"]
-          # }
         }
-        # --- END NEW ADDITIONS ---
       }
     }
 
@@ -251,30 +242,25 @@
         "
       }
 
-      # IP RENAMING LOGIC (applies to common fields)
+      # IP RENAMING LOGIC
       mutate {
-        copy => { "[host][ip]" => "device_ip" } # IP of the Logstash host that received the log
+        copy => { "[host][ip]" => "device_ip" }
       }
 
-      # Ensure client_ip is populated from src_ip if it exists (for other log types)
       if [src_ip] {
         mutate {
-          rename => { "src_ip" => "client_ip" } # Client IP from the log message (if not from kv_data)
+          rename => { "src_ip" => "client_ip" }
         }
       }
 
-      # --- GEOIP INTEGRATION START ---
-      # Apply GeoIP on client_ip if it exists
       if [client_ip] {
         geoip {
           source => "client_ip"
-          target => "client_geoip" # Use a distinct target for client IP geoip
+          target => "client_geoip"
           tag_on_failure => ["_geoip_client_failed"]
         }
       }
-      # Handle cases where client_geoip.location is missing
-      # Fallback lat, lon - Array Networks Bengaluru office.
-      if [client_ip] and ![client_geoip][location] { # Only fallback if client_ip was present
+      if [client_ip] and ![client_geoip][location] {
         mutate {
           add_field => {
             "[client_geoip][city_name]" => "Unknown"
@@ -288,16 +274,14 @@
         }
       }
 
-      # Optionally, apply GeoIP on destination_ip if it exists
       if [destination_ip] {
         geoip {
           source => "destination_ip"
-          target => "destination_geoip" # Use a distinct target for destination IP geoip
+          target => "destination_geoip"
           tag_on_failure => ["_geoip_destination_failed"]
         }
       }
-      # Handle cases where destination_geoip.location is missing
-      if [destination_ip] and ![destination_geoip][location] { # Only fallback if destination_ip was present
+      if [destination_ip] and ![destination_geoip][location] {
         mutate {
           add_field => {
             "[destination_geoip][city_name]" => "Unknown"
@@ -310,7 +294,6 @@
           add_tag => ["_geoip_destination_unresolved"]
         }
       }
-      # --- GEOIP INTEGRATION END ---
 
       if [device_ip] {
         jdbc_streaming {
@@ -353,7 +336,9 @@
         }
       } else if !("_grokparsefailure_an_welf_log" in [tags]) {
         mutate {
-          remove_tag => ["_grokparsefailure_rfc5424", "_grokparsefailure_an_welf_log_no_header", "_grokparsefailure_custom_nonstandard", "_grokparsefailure_bsd"]
+          remove_tag => ["_grokparsefailure_rfc542
+
+4", "_grokparsefailure_an_welf_log_no_header", "_grokparsefailure_custom_nonstandard", "_grokparsefailure_bsd"]
           add_tag => ["syslog_parsed", "an_welf_log_headered"]
         }
       } else if !("_grokparsefailure_an_welf_log_no_header" in [tags]) {
@@ -373,26 +358,22 @@
         }
       }
 
-      mutate {
-        remove_tag => ["rfc5424_attempt", "an_welf_log_attempt", "an_welf_log_no_header_attempt", "custom_nonstandard_attempt", "bsd_attempt"]
+      # Stage 4: Handle Unparsed Logs
+      if "_grokparsefailure_rfc5424" in [tags] and "_grokparsefailure_an_welf_log" in [tags] and "_grokparsefailure_an_welf_log_no_header" in [tags] and "_grokparsefailure_custom_nonstandard" in [tags] and "_grokparsefailure_bsd" in [tags] {
+        mutate {
+          add_tag => ["_parsefailure_syslog_unhandled"]
+          remove_tag => ["_grokparsefailure_rfc5424", "_grokparsefailure_an_welf_log", "_grokparsefailure_an_welf_log_no_header", "_grokparsefailure_custom_nonstandard", "_grokparsefailure_bsd"]
+        }
       }
     }
-
-    # Stage 4: Handle Unparsed Logs
-    if "_grokparsefailure_rfc5424" in [tags] and "_grokparsefailure_an_welf_log" in [tags] and "_grokparsefailure_an_welf_log_no_header" in [tags] and "_grokparsefailure_custom_nonstandard" in [tags] and "_grokparsefailure_bsd" in [tags] {
-      mutate {
-        add_tag => ["_parsefailure_syslog_unhandled"]
-        remove_tag => ["_grokparsefailure_rfc5424", "_grokparsefailure_an_welf_log", "_grokparsefailure_an_welf_log_no_header", "_grokparsefailure_custom_nonstandard", "_grokparsefailure_bsd"]
-      }
-    }
   }
 }
 
 output {
-  stdout { }
+  stdout { codec => rubydebug }
   opensearch {
     hosts => ["https://127.0.0.1:9200"]
-    index => "logstash-%{+YYYY.MM.dd}"
+    index => "acm-%{+YYYY.MM.dd}"
     user => "logstash"
     password => "Array@123"
     ssl => true
@@ -400,7 +381,4 @@
     cacert => "/etc/logstash/certs/root-ca.pem"
     manage_template => false
   }
-  stdout {
-    codec => rubydebug
-  }
 }
Index: /branches/amp_4_0/platform/dependencies/python/requirements.txt
===================================================================
--- /branches/amp_4_0/platform/dependencies/python/requirements.txt	(revision 2701)
+++ /branches/amp_4_0/platform/dependencies/python/requirements.txt	(working copy)
@@ -92,4 +92,5 @@
 webencodings==0.5.1
 wcwidth==0.2.13
 Whoosh==2.7.4
-yum-metadata-parser==1.1.4
\ No newline at end of file
+yum-metadata-parser==1.1.4
+opensearch-py==3.0.0
\ No newline at end of file
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/djproject/urls.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/djproject/urls.py	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/djproject/urls.py	(working copy)
@@ -16,7 +16,7 @@
 from hive.report.generate_report import handle_report_generation
 from hive.controller.backup_controller import handle_backup_req
 from hive.controller.restore_controller import handle_restore_req
-import cm.models.device_mgmt.device.Device
+from hive.an_opensearch import opensearch_proxy
 
 js_info_dict = {
     #'packages': ('your.app.package',),
@@ -24,8 +24,7 @@
 
 urlpatterns = [
     re_path(r'^ReloadAppNode/(?P<app_name>.*)$', reload_app_node),
-    re_path(r'^localfile/(?P<app>\w+)/(?P<filename>.*)$',
-        localfile_downloading_handler),
+    re_path(r'^localfile/(?P<app>\w+)/(?P<filename>.*)$', localfile_downloading_handler),
     re_path(r'^pipe/get/(?P<id>.*)$', hive_webpipe_handler),
     re_path(r'^configImport/(?P<model_path>.*)$', configImport),
     re_path(r'^configExport/(?P<model_path>.*)$', configExport),
@@ -73,6 +72,7 @@
     re_path(r'^kibana4/(?P<path>.*)$', KibanaProxyView.as_view()),
     # re_path(r'^kibana4/(?P<path>.*)', kibana_proxy),
     re_path(r'^elastic/(?P<path>.*)', elastic_proxy),
+    re_path(r'^log-analysis/(?P<path>.*)', opensearch_proxy),
     re_path(r'^reporting/(?P<app>\w+)/(?P<filename>.*)$', reporting_downloading_handler),
     re_path(r'^reporting_logo$', reporting_logo_handler),
     re_path(r'^cm/save_setting$', save_setting),
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/package.json
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/package.json	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/package.json	(working copy)
@@ -34,7 +34,8 @@
     "tslib": "^2.3.0",
     "xterm": "^5.3.0",
     "xterm-addon-fit": "^0.8.0",
-    "zone.js": "~0.15.0"
+    "zone.js": "~0.15.0",
+    "@ngxmc/datetime-picker": "20.1.0"
   },
   "devDependencies": {
     "@angular/build": "^20.0.3",
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/proxy.conf.json
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/proxy.conf.json	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/proxy.conf.json	(working copy)
@@ -1,6 +1,6 @@
 {
   "/api": {
-    "target": "https://192.168.85.47:8888",
+    "target": "http://192.168.85.41:8000",
     "secure": false,
     "changeOrigin": true,
     "pathRewrite": { "^/api": "" },
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/app.routes.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/app.routes.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/app.routes.ts	(working copy)
@@ -35,6 +35,10 @@
 import {AvxDeviceDetails} from './components/sub-components/avx-device-details/avx-device-details';
 import {AvxVaInstanceDetails} from './components/sub-components/avx-va-instance-details/avx-va-instance-details';
 import {Monitoring} from './components/monitoring/monitoring';
+import {LogAnalysis} from './components/log-analysis/log-analysis';
+import {
+  LogAnalysisSlbElaborate
+} from './components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate';
 
 
 export const routes: Routes = [
@@ -222,6 +226,14 @@
           {path: 'resources', component: Monitoring},
         ]
       },
+      {
+        path: 'log-analysis',
+        data: {roles: ['super_admin', 'device_admin', 'common_admin']},
+        children: [
+          {path: '', component: LogAnalysis},
+          {path: 'elaborate/:serviceName/:vip', component: LogAnalysisSlbElaborate},
+        ]
+      },
       {path: 'observability', component: Observability, data: {roles: ['super_admin', 'device_admin', 'common_admin']}},
       {path: '', redirectTo: 'dashboard', pathMatch: 'full'},
       // {path: '**', redirectTo: 'dashboard'}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/log-analysis/log-analysis.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/log-analysis/log-analysis.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/log-analysis/log-analysis.html	(working copy)
@@ -1 +1,19 @@
-<p>log-analysis works!</p>
+<div class="tab-container">
+  <mat-tab-group mat-stretch-tabs="false" animationDuration="0ms" [selectedIndex]="selectedTabIndex"
+                 (selectedTabChange)="onTabChange($event)">
+    <mat-tab label="APV - SLB - Virtual Services">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-log-analysis-slb-overview/>
+        </div>
+      </ng-template>
+    </mat-tab>
+<!--    <mat-tab label="SSLVPN Services">-->
+<!--      <ng-template matTabContent>-->
+<!--        <div class="tab-content">-->
+<!--          <app-log-analysis-ssl-vpn-overview/>-->
+<!--        </div>-->
+<!--      </ng-template>-->
+<!--    </mat-tab>-->
+  </mat-tab-group>
+</div>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/log-analysis/log-analysis.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/log-analysis/log-analysis.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/log-analysis/log-analysis.ts	(working copy)
@@ -1,11 +1,56 @@
-import { Component } from '@angular/core';
+import {Component, OnInit} from '@angular/core';
+import {ActivatedRoute, Router} from '@angular/router';
+import {MatTabChangeEvent} from '@angular/material/tabs';
+import {SharedModule} from '../../shared/shared-module';
+import {LogAnalysisSlbOverview} from '../sub-components/log-analysis-slb-overview/log-analysis-slb-overview';
+import {LogAnalysisSslVpnOverview} from '../sub-components/log-analysis-ssl-vpn-overview/log-analysis-ssl-vpn-overview';
 
 @Component({
   selector: 'app-log-analysis',
-  imports: [],
+  imports: [SharedModule, LogAnalysisSlbOverview, LogAnalysisSslVpnOverview],
   templateUrl: './log-analysis.html',
   styleUrl: './log-analysis.scss'
 })
-export class LogAnalysis {
+export class LogAnalysis implements OnInit {
 
+  selectedTabIndex: number = 0;
+  private tabNames: string[] = [
+    'APV - SLB - Virtual Services',
+    'SSLVPN Services',
+  ];
+
+  constructor(private _route: ActivatedRoute, private _router: Router) {
+  }
+
+  ngOnInit(): void {
+    this._route.queryParams.subscribe(params => {
+      const tabParam = params['tab'];
+      if (tabParam) {
+        const index = this.tabNames.indexOf(tabParam);
+        if (index !== -1) {
+          this.selectedTabIndex = index;
+        } else {
+          this.selectedTabIndex = 0;
+        }
+      } else {
+        this.updateQueryParams(this.selectedTabIndex);
+      }
+    });
+  }
+
+  onTabChange(event: MatTabChangeEvent): void {
+    this.selectedTabIndex = event.index;
+    this.updateQueryParams(event.index);
+  }
+
+  private updateQueryParams(tabIndex: number): void {
+    const tabName = this.tabNames[tabIndex];
+    if (tabName) {
+      this._router.navigate([], {
+        relativeTo: this._route,
+        queryParams: {tab: tabName},
+        queryParamsHandling: 'merge'
+      });
+    }
+  }
 }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/monitoring/monitoring.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/monitoring/monitoring.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/monitoring/monitoring.html	(working copy)
@@ -1 +1,33 @@
-<p>monitoring works!</p>
+<div class="tab-container">
+  <mat-tab-group mat-stretch-tabs="false" animationDuration="0ms" [selectedIndex]="selectedTabIndex"
+                 (selectedTabChange)="onTabChange($event)">
+    <mat-tab label="Devices">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-resource-monitoring-devices/>
+        </div>
+      </ng-template>
+    </mat-tab>
+    <mat-tab label="APV">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-resource-monitoring-apv/>
+        </div>
+      </ng-template>
+    </mat-tab>
+    <mat-tab label="ASF">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-resource-monitoring-asf/>
+        </div>
+      </ng-template>
+    </mat-tab>
+    <mat-tab label="SSL VPN">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-resource-monitoring-ssl-vpn/>
+        </div>
+      </ng-template>
+    </mat-tab>
+  </mat-tab-group>
+</div>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/monitoring/monitoring.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/monitoring/monitoring.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/monitoring/monitoring.ts	(working copy)
@@ -1,11 +1,60 @@
-import { Component } from '@angular/core';
+import {Component, OnInit} from '@angular/core';
+import {SharedModule} from '../../shared/shared-module';
+import {ActivatedRoute, Router} from '@angular/router';
+import {MatTabChangeEvent} from '@angular/material/tabs';
+import {ResourceMonitoringDevices} from '../sub-components/resource-monitoring-devices/resource-monitoring-devices';
+import {ResourceMonitoringApv} from '../sub-components/resource-monitoring-apv/resource-monitoring-apv';
+import {ResourceMonitoringSslVpn} from '../sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn';
+import {ResourceMonitoringAsf} from '../sub-components/resource-monitoring-asf/resource-monitoring-asf';
 
 @Component({
   selector: 'app-monitoring',
-  imports: [],
+  imports: [SharedModule, ResourceMonitoringDevices, ResourceMonitoringApv, ResourceMonitoringSslVpn, ResourceMonitoringAsf],
   templateUrl: './monitoring.html',
   styleUrl: './monitoring.scss'
 })
-export class Monitoring {
+export class Monitoring implements OnInit {
 
+  selectedTabIndex: number = 0;
+  private tabNames: string[] = [
+    'Devices',
+    'APV',
+    'ASF',
+    'SSL VPN',
+  ];
+
+  constructor(private _route: ActivatedRoute, private _router: Router) {
+  }
+
+  ngOnInit(): void {
+    this._route.queryParams.subscribe(params => {
+      const tabParam = params['tab'];
+      if (tabParam) {
+        const index = this.tabNames.indexOf(tabParam);
+        if (index !== -1) {
+          this.selectedTabIndex = index;
+        } else {
+          this.selectedTabIndex = 0;
+        }
+      } else {
+        this.updateQueryParams(this.selectedTabIndex);
+      }
+    });
+  }
+
+  onTabChange(event: MatTabChangeEvent): void {
+    this.selectedTabIndex = event.index;
+    this.updateQueryParams(event.index);
+  }
+
+  private updateQueryParams(tabIndex: number): void {
+    const tabName = this.tabNames[tabIndex];
+    if (tabName) {
+      this._router.navigate([], {
+        relativeTo: this._route,
+        queryParams: {tab: tabName},
+        queryParamsHandling: 'merge'
+      });
+    }
+  }
 }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/admin-aaa/admin-aaa.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/admin-aaa/admin-aaa.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/admin-aaa/admin-aaa.html	(working copy)
@@ -1,210 +1,221 @@
-<div>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>AAA Settings</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <form
-        (ngSubmit)="updateAAASettings()"
-        [formGroup]="aaaForm"
-        class="common-form"
-      >
-        <div class="form-field-wrapper">
-          <label for="enable_aaa" class="form-label">External AAA</label>
-          <mat-slide-toggle formControlName="enable_aaa"></mat-slide-toggle>
-        </div>
-        <div class="form-field-wrapper">
-          <label for="enable_aaa_authorize" class="form-label">External AAA Authorization</label>
-          <mat-slide-toggle formControlName="enable_aaa_authorize"></mat-slide-toggle>
-        </div>
-        <div class="form-field-wrapper">
-          <label for="method" class="form-label">Method</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <mat-select formControlName="method">
-              @for (_auth of authMethod; track _auth) {
-                <mat-option [value]="_auth.value">{{ _auth.displayName }}</mat-option>
-              }
-            </mat-select>
-            @if (aaaForm.get('method')?.invalid && aaaForm.get('method')?.touched) {
-              <mat-error>
-                @if (aaaForm.get('method')?.errors?.['required']) {
-                  Method is required.
-                } @else {
-                  Invalid method format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <button
-          type="submit"
-          mat-raised-button
-          color="primary">
-          Submit
-        </button>
-      </form>
-    </mat-card-content>
-  </mat-card>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>AAA - es01</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <form
-        (ngSubmit)="updateESForm('es01')"
-        [formGroup]="esForm1"
-        class="common-form"
-      >
-        <div class="form-field-wrapper">
-          <label for="host_name" class="form-label">Hostname</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="host_name"
-              formControlName="host_name"
-              matInput
-              placeholder="Hostname"
-              type="text"
-            />
-            @if (esForm1.get('host_name')?.invalid && esForm1.get('host_name')?.touched) {
-              <mat-error>
-                @if (esForm1.get('host_name')?.errors?.['required']) {
-                  Hostname is required.
-                } @else {
-                  Invalid hostname format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="form-field-wrapper">
-          <label for="port" class="form-label">Port</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="port"
-              formControlName="port"
-              matInput
-              placeholder="Port"
-              type="number"
-            />
-            @if (esForm1.get('port')?.invalid && esForm1.get('port')?.touched) {
-              <mat-error>
-                @if (esForm1.get('port')?.errors?.['required']) {
-                  Port is required.
-                } @else {
-                  Port value must be between 0 and 65535.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="form-field-wrapper">
-          <label for="secret" class="form-label">Secret</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="secret"
-              formControlName="secret"
-              matInput
-              placeholder="Secret"
-              type="password"
-            />
-            @if (esForm1.get('secret')?.invalid && esForm1.get('secret')?.touched) {
-              <mat-error>
-                @if (esForm1.get('secret')?.errors?.['required']) {
-                  Secret is required.
-                } @else {
-                  Invalid secret format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="button-container-center">
-          <button type="submit" mat-raised-button color="primary">Submit</button> &nbsp;&nbsp;&nbsp;&nbsp;
-          <button type="button" mat-raised-button class="warning secondary-btn-center" (click)="deleteAAAESSettings('es01')">Clear Server Config
-          </button>
-        </div>
-      </form>
-    </mat-card-content>
-  </mat-card>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>AAA - es02</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <form
-        (ngSubmit)="updateESForm('es02')"
-        [formGroup]="esForm2"
-        class="common-form"
-      >
-        <div class="form-field-wrapper">
-          <label for="host_name1" class="form-label">Hostname</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="host_name1"
-              formControlName="host_name"
-              matInput
-              placeholder="Hostname"
-              type="text"
-            />
-            @if (esForm2.get('host_name')?.invalid && esForm2.get('host_name')?.touched) {
-              <mat-error>
-                @if (esForm2.get('host_name')?.errors?.['required']) {
-                  Hostname is required.
-                } @else {
-                  Invalid hostname format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="form-field-wrapper">
-          <label for="port1" class="form-label">Port</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="port1"
-              formControlName="port"
-              matInput
-              placeholder="Port"
-              type="number"
-            />
-            @if (esForm2.get('port')?.invalid && esForm2.get('port')?.touched) {
-              <mat-error>
-                @if (esForm2.get('port')?.errors?.['required']) {
-                  Port is required.
-                } @else {
-                  Port value must be between 0 and 65535.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="form-field-wrapper">
-          <label for="secret1" class="form-label">Secret</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="secret1"
-              formControlName="secret"
-              matInput
-              placeholder="Secret"
-              type="password"
-            />
-            @if (esForm2.get('secret')?.invalid && esForm2.get('secret')?.touched) {
-              <mat-error>
-                @if (esForm2.get('secret')?.errors?.['required']) {
-                  Secret is required.
-                } @else {
-                  Invalid secret format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="button-container-center">
-          <button type="submit" mat-raised-button color="primary">Submit</button> &nbsp;&nbsp;&nbsp;&nbsp;
-          <button type="button" mat-raised-button class="warning secondary-btn-center" (click)="deleteAAAESSettings('es02')">Clear Server Config
-          </button>
-        </div>
-      </form>
-    </mat-card-content>
-  </mat-card>
-</div>
+<mat-tab-group mat-stretch-tabs="false" animationDuration="0ms">
+  <mat-tab label="Interfaces">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <form
+              (ngSubmit)="updateAAASettings()"
+              [formGroup]="aaaForm"
+              class="common-form"
+            >
+              <div class="form-field-wrapper">
+                <label for="enable_aaa" class="form-label">External AAA</label>
+                <mat-slide-toggle formControlName="enable_aaa"></mat-slide-toggle>
+              </div>
+              <div class="form-field-wrapper">
+                <label for="enable_aaa_authorize" class="form-label">External AAA Authorization</label>
+                <mat-slide-toggle formControlName="enable_aaa_authorize"></mat-slide-toggle>
+              </div>
+              <div class="form-field-wrapper">
+                <label for="method" class="form-label">Method</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <mat-select formControlName="method">
+                    @for (_auth of authMethod; track _auth) {
+                      <mat-option [value]="_auth.value">{{ _auth.displayName }}</mat-option>
+                    }
+                  </mat-select>
+                  @if (aaaForm.get('method')?.invalid && aaaForm.get('method')?.touched) {
+                    <mat-error>
+                      @if (aaaForm.get('method')?.errors?.['required']) {
+                        Method is required.
+                      } @else {
+                        Invalid method format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <button
+                type="submit"
+                mat-raised-button
+                color="primary">
+                Submit
+              </button>
+            </form>
+          </mat-card-content>
+        </mat-card>
+      </div>
+    </ng-template>
+  </mat-tab>
+  <mat-tab label="AAA - es01">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <form
+              (ngSubmit)="updateESForm('es01')"
+              [formGroup]="esForm1"
+              class="common-form"
+            >
+              <div class="form-field-wrapper">
+                <label for="host_name" class="form-label">Hostname</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="host_name"
+                    formControlName="host_name"
+                    matInput
+                    placeholder="Hostname"
+                    type="text"
+                  />
+                  @if (esForm1.get('host_name')?.invalid && esForm1.get('host_name')?.touched) {
+                    <mat-error>
+                      @if (esForm1.get('host_name')?.errors?.['required']) {
+                        Hostname is required.
+                      } @else {
+                        Invalid hostname format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <div class="form-field-wrapper">
+                <label for="port" class="form-label">Port</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="port"
+                    formControlName="port"
+                    matInput
+                    placeholder="Port"
+                    type="number"
+                  />
+                  @if (esForm1.get('port')?.invalid && esForm1.get('port')?.touched) {
+                    <mat-error>
+                      @if (esForm1.get('port')?.errors?.['required']) {
+                        Port is required.
+                      } @else {
+                        Port value must be between 0 and 65535.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <div class="form-field-wrapper">
+                <label for="secret" class="form-label">Secret</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="secret"
+                    formControlName="secret"
+                    matInput
+                    placeholder="Secret"
+                    type="password"
+                  />
+                  @if (esForm1.get('secret')?.invalid && esForm1.get('secret')?.touched) {
+                    <mat-error>
+                      @if (esForm1.get('secret')?.errors?.['required']) {
+                        Secret is required.
+                      } @else {
+                        Invalid secret format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <div class="button-container-center">
+                <button type="submit" mat-raised-button color="primary">Submit</button> &nbsp;&nbsp;&nbsp;&nbsp;
+                <button type="button" mat-raised-button class="warning secondary-btn-center"
+                        (click)="deleteAAAESSettings('es01')">Clear Server Config
+                </button>
+              </div>
+            </form>
+          </mat-card-content>
+        </mat-card>
+      </div>
+    </ng-template>
+  </mat-tab>
+  <mat-tab label="AAA - es02">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <form
+              (ngSubmit)="updateESForm('es02')"
+              [formGroup]="esForm2"
+              class="common-form"
+            >
+              <div class="form-field-wrapper">
+                <label for="host_name1" class="form-label">Hostname</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="host_name1"
+                    formControlName="host_name"
+                    matInput
+                    placeholder="Hostname"
+                    type="text"
+                  />
+                  @if (esForm2.get('host_name')?.invalid && esForm2.get('host_name')?.touched) {
+                    <mat-error>
+                      @if (esForm2.get('host_name')?.errors?.['required']) {
+                        Hostname is required.
+                      } @else {
+                        Invalid hostname format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <div class="form-field-wrapper">
+                <label for="port1" class="form-label">Port</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="port1"
+                    formControlName="port"
+                    matInput
+                    placeholder="Port"
+                    type="number"
+                  />
+                  @if (esForm2.get('port')?.invalid && esForm2.get('port')?.touched) {
+                    <mat-error>
+                      @if (esForm2.get('port')?.errors?.['required']) {
+                        Port is required.
+                      } @else {
+                        Port value must be between 0 and 65535.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <div class="form-field-wrapper">
+                <label for="secret1" class="form-label">Secret</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="secret1"
+                    formControlName="secret"
+                    matInput
+                    placeholder="Secret"
+                    type="password"
+                  />
+                  @if (esForm2.get('secret')?.invalid && esForm2.get('secret')?.touched) {
+                    <mat-error>
+                      @if (esForm2.get('secret')?.errors?.['required']) {
+                        Secret is required.
+                      } @else {
+                        Invalid secret format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <div class="button-container-center">
+                <button type="submit" mat-raised-button color="primary">Submit</button> &nbsp;&nbsp;&nbsp;&nbsp;
+                <button type="button" mat-raised-button class="warning secondary-btn-center"
+                        (click)="deleteAAAESSettings('es02')">Clear Server Config
+                </button>
+              </div>
+            </form>
+          </mat-card-content>
+        </mat-card>
+      </div>
+    </ng-template>
+  </mat-tab>
+</mat-tab-group>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.html	(working copy)
@@ -22,7 +22,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="fileName">
       <th mat-header-cell *matHeaderCellDef> Filename</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.ts	(working copy)
@@ -10,11 +10,13 @@
 import {DeviceService} from '../../../services/device-service';
 import {SystemService} from '../../../services/system-service';
 import {Confirmation} from '../../../services/confirmation';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-backup-files',
   imports: [
-    SharedModule
+    SharedModule,
+    GlobalSerialPipe
   ],
   templateUrl: './device-backup-files.html',
   styleUrl: './device-backup-files.scss'
@@ -279,7 +281,7 @@
 @Component({
   selector: 'show-tasks-by-name',
   templateUrl: './show-tasks-by-name.html',
-  imports: [SharedModule]
+  imports: [SharedModule, GlobalSerialPipe]
 })
 export class ShowTasksByNameDialog implements AfterViewInit {
   readonly data = inject(MAT_DIALOG_DATA);
@@ -327,13 +329,6 @@
       })
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   onCancel(): void {
     this.dialogRef.close(false);
   }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/show-tasks-by-name.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/show-tasks-by-name.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/show-tasks-by-name.html	(working copy)
@@ -5,7 +5,7 @@
     <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
       <ng-container matColumnDef="serial">
         <th mat-header-cell *matHeaderCellDef> No.</th>
-        <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+        <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
       </ng-container>
       <ng-container matColumnDef="name">
         <th mat-header-cell *matHeaderCellDef> Filename</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.html	(working copy)
@@ -2,7 +2,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="deviceName">
       <th mat-header-cell *matHeaderCellDef>Configuration Filename</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.ts	(working copy)
@@ -10,11 +10,13 @@
 import {CloneConfigDialog, ShowTasksByNameDialog} from '../device-backup-files/device-backup-files';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {Subscription} from 'rxjs';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-cloned-files',
   imports: [
-    SharedModule
+    SharedModule,
+    GlobalSerialPipe
   ],
   templateUrl: './device-cloned-files.html',
   styleUrl: './device-cloned-files.scss'
@@ -141,13 +143,6 @@
       })
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   editDeviceConfiguration(_device: any) {
     this.dialogConfig.data = {
       config: _device,
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.html	(working copy)
@@ -24,7 +24,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="deviceName">
       <th mat-header-cell *matHeaderCellDef>Device Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.ts	(working copy)
@@ -11,10 +11,11 @@
 import {CreateDeviceConfigDialog, ShowTasksByNameDialog} from '../device-backup-files/device-backup-files';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {Subscription} from 'rxjs';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-config-overview',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './device-config-overview.html',
   styleUrl: './device-config-overview.scss'
 })
@@ -184,13 +185,6 @@
     this._router.navigate(['/configuration-hub/backup', _device.name], {
       state: {deviceDetails: this.deviceBackupsMap[_device.name]},
     });
-  }
-
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
   }
 
   compareDeviceConfigLastBackup(_device: any) {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.html	(working copy)
@@ -5,7 +5,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="deviceName">
       <th mat-header-cell *matHeaderCellDef>Configuration Filename</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.ts	(working copy)
@@ -17,10 +17,11 @@
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {Storage} from '../../../services/storage';
 import {SystemService} from '../../../services/system-service';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-custom-config-overview',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './device-custom-config-overview.html',
   styleUrl: './device-custom-config-overview.scss'
 })
@@ -136,13 +137,6 @@
           this._notification.showError(error.message);
         }
       })
-  }
-
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
   }
 
   editDeviceConfiguration(_config: any) {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.html	(working copy)
@@ -9,7 +9,7 @@
     <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
       <ng-container matColumnDef="serial">
         <th mat-header-cell *matHeaderCellDef> No.</th>
-        <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+        <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
       </ng-container>
       <ng-container matColumnDef="tKey">
         <th mat-header-cell *matHeaderCellDef>Template Keyword</th>
@@ -56,7 +56,7 @@
     <table mat-table [dataSource]="dataSource1" class="mat-elevation-z1">
       <ng-container matColumnDef="serial">
         <th mat-header-cell *matHeaderCellDef> No.</th>
-        <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+        <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
       </ng-container>
       <ng-container matColumnDef="device">
         <th mat-header-cell *matHeaderCellDef>Device IP</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.ts	(working copy)
@@ -9,10 +9,11 @@
 import {take} from 'rxjs/operators';
 import {SharedModule} from '../../../shared/shared-module';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-custom-config-templates',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './device-custom-config-templates.html',
   styleUrl: './device-custom-config-templates.scss'
 })
@@ -101,13 +102,6 @@
         this._cdRef.detectChanges();
       }
     })
-  }
-
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
   }
 
   addCustomTemplate(): void {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-details/device-details.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-details/device-details.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-details/device-details.ts	(working copy)
@@ -37,12 +37,12 @@
   deviceSettingsForm: FormGroup;
 
   constructor(
-    private route: ActivatedRoute,
-    private router: Router,
-    private deviceService: DeviceService,
-    private notification: NotificationService,
-    private formBuilder: FormBuilder) {
-    this.deviceSettingsForm = this.formBuilder.group({
+    private _route: ActivatedRoute,
+    private _router: Router,
+    private _device: DeviceService,
+    private _notification: NotificationService,
+    private _fB: FormBuilder) {
+    this.deviceSettingsForm = this._fB.group({
       portNumber: ['9997', [Validators.required, Validators.min(0), Validators.max(65535)]],
       apiUsername: ['', Validators.required],
       apiPassword: ['', Validators.required],
@@ -59,7 +59,7 @@
   }
 
   ngOnInit(): void {
-    this.deviceName = this.route.snapshot.paramMap.get('deviceName');
+    this.deviceName = this._route.snapshot.paramMap.get('deviceName');
     this.deviceData = history.state.deviceData;
     this.groups = history.state.groups;
     let licenseData: any = {};
@@ -122,7 +122,7 @@
   }
 
   backToManagedDevices(): void {
-    this.router.navigate(['/inventory/devices']);
+    this._router.navigate(['/inventory/devices']);
   }
 
   processConfigData(configData: any): any {
@@ -179,27 +179,27 @@
     let rawPayload = new FormData();
     rawPayload.set('action', event?.checked ? 'EnableMonitoring' : 'DisableMonitoring');
     rawPayload.set('options', JSON.stringify({"__pk_list": [JSON.stringify(payload)]}));
-    this.deviceService.updateDeviceMonitoringState(rawPayload)
+    this._device.updateDeviceMonitoringState(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
           if (result && result.length > 1) {
             if (result[0]) {
-              this.notification.showSuccess(`${this.deviceData?.name} updated successfully!`);
+              this._notification.showSuccess(`${this.deviceData?.name} updated successfully!`);
               this.backToManagedDevices();
             } else {
-              this.notification.showError(`Failed to update device: ${result[1]}`);
+              this._notification.showError(`Failed to update device: ${result[1]}`);
             }
           }
         },
         error: () => {
-          this.notification.showError('Update Failed.');
+          this._notification.showError('Update Failed.');
         }
       })
   }
 
   getDeviceConfiguration(deviceName: string): void {
-    this.deviceService.getDeviceConfiguration(deviceName)
+    this._device.getDeviceConfiguration(deviceName)
       .pipe(take(1)).subscribe({
       next: (result: any) => {
         if (result && result.length > 1) {
@@ -207,7 +207,7 @@
         }
       },
       error: error => {
-        this.notification.showError(`Error: ${error?.message}`);
+        this._notification.showError(`Error: ${error?.message}`);
       }
     })
   }
@@ -251,21 +251,21 @@
 
     const postDataJsonString: string = JSON.stringify(payload);
     const encodedPostData: string = encodeURIComponent(postDataJsonString);
-    this.deviceService.updateDevice(this.deviceData?.id, this.deviceData?.type, this.deviceData?.name, encodedPostData)
+    this._device.updateDevice(this.deviceData?.id, this.deviceData?.type, this.deviceData?.name, encodedPostData)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
           if (result && result.length > 1) {
             if (result[0]) {
-              this.notification.showSuccess(`${this.deviceData?.name} updated successfully!`);
+              this._notification.showSuccess(`${this.deviceData?.name} updated successfully!`);
               this.backToManagedDevices();
             } else {
-              this.notification.showError(`Failed to update device: ${result[1]}`);
+              this._notification.showError(`Failed to update device: ${result[1]}`);
             }
           }
         },
         error: () => {
-          this.notification.showError('Update Failed.');
+          this._notification.showError('Update Failed.');
         }
       })
   }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-groups/device-groups.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-groups/device-groups.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-groups/device-groups.html	(working copy)
@@ -16,7 +16,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="name">
       <th mat-header-cell *matHeaderCellDef> Group Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-groups/device-groups.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-groups/device-groups.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-groups/device-groups.ts	(working copy)
@@ -7,12 +7,12 @@
 import {Confirmation} from '../../../services/confirmation';
 import {MatDialog, MatDialogRef} from '@angular/material/dialog';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
-import {AlertMsg} from '../../../services/alert-msg';
 import {MatPaginator} from '@angular/material/paginator';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-groups',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './device-groups.html',
   styleUrl: './device-groups.scss'
 })
@@ -26,10 +26,9 @@
   @ViewChild(MatPaginator) paginator!: MatPaginator;
 
   constructor(
-    private notification: NotificationService,
-    private deviceService: DeviceService,
-    private alertMsg: AlertMsg,
-    private confirmationService: Confirmation
+    private _notification: NotificationService,
+    private _device: DeviceService,
+    private _confirmation: Confirmation
   ) {
     this.getDeviceGroups();
     this.dataSource.paginator = this.paginator;
@@ -42,7 +41,7 @@
     let rawPayload = new FormData();
     rawPayload.set('action', 'FilterRoleDeviceGroups');
     rawPayload.set('options', JSON.stringify({"role_id": roleId}));
-    this.deviceService.getDeviceGroups(rawPayload)
+    this._device.getDeviceGroups(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
@@ -57,7 +56,7 @@
         },
         error: (error: { message: string; }) => {
           console.log(error);
-          this.notification.showError(error.message);
+          this._notification.showError(error.message);
         }
       })
   }
@@ -88,7 +87,7 @@
     if (deviceGroup.device_list.length > 0) {
       confirmMsg = "Deleting this device group will also remove all devices associated with it. Are you sure you want to proceed?"
     }
-    this.confirmationService.openConfirmDialog({
+    this._confirmation.openConfirmDialog({
       title: `Delete ${groupName}?`,
       message: confirmMsg,
       confirmButtonText: 'Yes, Delete It',
@@ -99,16 +98,16 @@
       if (result) {
         let rawPayload = new FormData();
         rawPayload.set('pk', JSON.stringify({"name": groupName}));
-        this.deviceService.deleteDeviceGroup(rawPayload)
+        this._device.deleteDeviceGroup(rawPayload)
           .pipe(take(1))
           .subscribe({
             next: (result: any) => {
               // ToDo: Backend fix required.
               if (result && result.length > 1) {
                 if (!result[0]) {
-                  this.notification.showError(`${result[1]}`);
+                  this._notification.showError(`${result[1]}`);
                 } else {
-                  this.notification.showSuccess(`${groupName} deleted successfully!`);
+                  this._notification.showSuccess(`${groupName} deleted successfully!`);
                   this.getDeviceGroups();
                 }
               }
@@ -116,15 +115,15 @@
             error: (err) => {
               if (err.status === 200) {
                 // ToDo: Backend fix required.
-                this.notification.showSuccess(`${groupName} deleted successfully!`);
+                this._notification.showSuccess(`${groupName} deleted successfully!`);
                 this.getDeviceGroups();
               } else {
-                this.notification.showError('Deletion Failed.');
+                this._notification.showError('Deletion Failed.');
               }
             }
           })
       } else {
-        this.notification.showSuccess('Deletion cancelled.');
+        this._notification.showSuccess('Deletion cancelled.');
       }
     });
   }
@@ -135,15 +134,15 @@
       if (result) {
         let rawPayload = new FormData();
         rawPayload.set('post_data', JSON.stringify({"name": result?.groupName}));
-        this.deviceService.addDeviceGroup(rawPayload)
+        this._device.addDeviceGroup(rawPayload)
           .pipe(take(1))
           .subscribe({
             next: () => {
-              this.notification.showSuccess(`${result?.groupName} added successfully!`);
+              this._notification.showSuccess(`${result?.groupName} added successfully!`);
               this.getDeviceGroups();
             },
             error: () => {
-              this.notification.showError('Creation Failed.');
+              this._notification.showError('Creation Failed.');
             }
           })
       }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/devices/devices.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/devices/devices.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/devices/devices.html	(working copy)
@@ -16,7 +16,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="deviceName">
       <th mat-header-cell *matHeaderCellDef> Device Name</th>
@@ -77,7 +77,7 @@
     <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
     <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
     <tr class="mat-row" *matNoDataRow>
-      <td class="mat-cell" colspan="4">No data matching the filter "{{ input.value }}"</td>
+      <td class="mat-cell" colspan="9">No data matching the filter "{{ input.value }}"</td>
     </tr>
   </table>
 </div>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/devices/devices.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/devices/devices.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/devices/devices.ts	(working copy)
@@ -10,13 +10,16 @@
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {CustomValidators} from '../../../utils/custom-validators';
 import {Router} from '@angular/router';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 export interface KeyValuePair {
   key: string;
   value: any;
 }
+
 @Component({
-  selector: 'app-devices', imports: [SharedModule], templateUrl: './devices.html', styleUrl: './devices.scss'
+  selector: 'app-devices',
+  imports: [SharedModule, GlobalSerialPipe], templateUrl: './devices.html', styleUrl: './devices.scss'
 })
 export class Devices {
 
@@ -29,13 +32,13 @@
   deviceType: any = null;
 
   constructor(
-    private notification: NotificationService,
-    private deviceService: DeviceService,
-    private confirmationService: Confirmation,
-    private storage: Storage,
-    private router: Router
+    private _notification: NotificationService,
+    private _device: DeviceService,
+    private _confirmation: Confirmation,
+    private _storage: Storage,
+    private _router: Router
   ) {
-    this.deviceType = this.storage.getItem('deviceType');
+    this.deviceType = this._storage.getItem('deviceType');
     this.getDeviceGroups();
     if (this.deviceType === null) {
       this.getDevicesType();
@@ -43,12 +46,12 @@
   }
 
   getDevicesType() {
-    this.deviceService.getDeviceTypeList().pipe(take(1)).subscribe({
+    this._device.getDeviceTypeList().pipe(take(1)).subscribe({
       next: result => {
-        this.storage.setItem('deviceType', JSON.stringify(result));
+        this._storage.setItem('deviceType', JSON.stringify(result));
       },
       error: error => {
-        this.notification.showError(`Error: ${error?.message}`);
+        this._notification.showError(`Error: ${error?.message}`);
       }
     })
   }
@@ -61,7 +64,7 @@
     let rawPayload = new FormData();
     rawPayload.set('action', 'FilterRoleDeviceGroups');
     rawPayload.set('options', JSON.stringify({"role_id": roleId}));
-    this.deviceService.getDeviceGroups(rawPayload)
+    this._device.getDeviceGroups(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
@@ -79,7 +82,7 @@
           }
         }, error: (error: { message: string; }) => {
           console.log(error);
-          this.notification.showError(error.message);
+          this._notification.showError(error.message);
         }
       })
   }
@@ -90,9 +93,6 @@
   }
 
   getDeviceBuildInfo() {
-    this.dialogConfig.position = {
-      bottom: '0px', right: '0px',
-    }
     this.dialogConfig.width = '40%';
     this.dialogConfig.height = '60%';
     const dialogRef = this.dialog.open(DevicesBuildInfoDialog, this.dialogConfig);
@@ -103,7 +103,7 @@
   confirmDelete(device: any): void {
     let deviceName = device?.name;
     let confirmMsg = `Are you sure you want to permanently delete "${deviceName}"? This action cannot be undone.`
-    this.confirmationService.openConfirmDialog({
+    this._confirmation.openConfirmDialog({
       title: `Delete ${deviceName}?`,
       message: confirmMsg,
       confirmButtonText: 'Yes, Delete It',
@@ -118,16 +118,16 @@
           "id": device?.id,
           "type": device?.type,
         }));
-        this.deviceService.deleteDevice(rawPayload)
+        this._device.deleteDevice(rawPayload)
           .pipe(take(1))
           .subscribe({
             next: (result: any) => {
               // ToDo: Backend fix required.
               if (result && result.length > 1) {
                 if (!result[0]) {
-                  this.notification.showError(`${result[1]}`);
+                  this._notification.showError(`${result[1]}`);
                 } else {
-                  this.notification.showSuccess(`${deviceName} deleted successfully!`);
+                  this._notification.showSuccess(`${deviceName} deleted successfully!`);
                   this.getDeviceGroups();
                 }
               }
@@ -135,22 +135,23 @@
             error: (err) => {
               if (err.status === 200) {
                 // ToDo: Backend fix required.
-                this.notification.showSuccess(`${deviceName} deleted successfully!`);
+                this._notification.showSuccess(`${deviceName} deleted successfully!`);
                 this.getDeviceGroups();
               } else {
-                this.notification.showError('Deletion Failed.');
+                this._notification.showError('Deletion Failed.');
               }
             }
           })
       } else {
-        this.notification.showSuccess('Deletion cancelled.');
+        this._notification.showSuccess('Deletion cancelled.');
       }
     });
   }
+
   openWebConsole(device: any): void {
-    const url = this.router.serializeUrl(
-      this.router.createUrlTree(['/inventory/web-console'], {
-        queryParams: { device_id: device?.id, device_name: device?.name }
+    const url = this._router.serializeUrl(
+      this._router.createUrlTree(['/inventory/web-console'], {
+        queryParams: {device_id: device?.id, device_name: device?.name}
       })
     );
     window.open(url, '_blank');
@@ -159,7 +160,7 @@
   confirmSave(device: any): void {
     let deviceName = device?.name;
     let confirmMsg = `This action will save the device's (${deviceName}) configuration by CLI command 'write memory'. Are you sure you want to do this?`
-    this.confirmationService.openConfirmDialog({
+    this._confirmation.openConfirmDialog({
       title: `Save configuration - ${deviceName}?`,
       message: confirmMsg,
       confirmButtonText: 'Yes, Save It',
@@ -170,21 +171,23 @@
       if (result) {
         let rawPayload = new FormData();
         rawPayload.set('action', 'SaveConfigurations')
-        rawPayload.set('options', JSON.stringify({"__pk_list": [JSON.stringify({
+        rawPayload.set('options', JSON.stringify({
+          "__pk_list": [JSON.stringify({
             "name": deviceName,
             "id": device?.id,
             "type": device?.type,
-          })]}))
-        this.deviceService.saveDevice(rawPayload)
+          })]
+        }))
+        this._device.saveDevice(rawPayload)
           .pipe(take(1))
           .subscribe({
             next: (result: any) => {
               // ToDo: Backend fix required.
               if (result && result.length > 1) {
                 if (!result[0]) {
-                  this.notification.showError(`${result[1]}`);
+                  this._notification.showError(`${result[1]}`);
                 } else {
-                  this.notification.showSuccess(`${deviceName} saved successfully!`);
+                  this._notification.showSuccess(`${deviceName} saved successfully!`);
                   this.getDeviceGroups();
                 }
               }
@@ -192,23 +195,20 @@
             error: (err) => {
               if (err.status === 200) {
                 // ToDo: Backend fix required.
-                this.notification.showSuccess(`${deviceName} saved successfully!`);
+                this._notification.showSuccess(`${deviceName} saved successfully!`);
                 this.getDeviceGroups();
               } else {
-                this.notification.showError('Save Failed.');
+                this._notification.showError('Save Failed.');
               }
             }
           })
       } else {
-        this.notification.showSuccess('Save cancelled.');
+        this._notification.showSuccess('Save cancelled.');
       }
     });
   }
 
   addDevice() {
-    this.dialogConfig.position = {
-      bottom: '0px', right: '0px',
-    }
     this.dialogConfig.width = '65%';
     this.dialogConfig.height = '80%';
     this.dialogConfig.data = {
@@ -224,15 +224,12 @@
   }
 
   goToDetails(device: any) {
-    this.router.navigate(['/inventory/devices', device.name], {
-      state: { deviceData: device, groups: this.groups }
+    this._router.navigate(['/inventory/devices', device.name], {
+      state: {deviceData: device, groups: this.groups}
     });
   }
 
   showLicenseDialog(device: any): void {
-    this.dialogConfig.position = {
-      bottom: '0px', right: '0px',
-    }
     this.dialogConfig.width = '40%';
     this.dialogConfig.height = '60%';
     this.dialogConfig.data = {
@@ -273,7 +270,7 @@
   displayedColumns: string[] = ['serial', 'deviceName', 'currentBuild', 'availableBuild'];
   dataSource = new MatTableDataSource(this.buildInfo);
 
-  constructor(private deviceService: DeviceService, private notification: NotificationService) {
+  constructor(private _device: DeviceService, private _notification: NotificationService) {
   }
 
   ngOnInit() {
@@ -285,7 +282,7 @@
   }
 
   getDeviceBuildInfo(): void {
-    this.deviceService.getDeviceBuildInfo()
+    this._device.getDeviceBuildInfo()
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
@@ -294,7 +291,7 @@
             this.dataSource = new MatTableDataSource(this.buildInfo);
           }
         }, error: (error: { message: string; }) => {
-          this.notification.showError(error.message);
+          this._notification.showError(error.message);
         }
       })
   }
@@ -312,11 +309,11 @@
   deviceForm: FormGroup;
 
   constructor(
-    private formBuilder: FormBuilder,
-    private deviceService: DeviceService,
-    private notification: NotificationService,
+    private _fB: FormBuilder,
+    private _device: DeviceService,
+    private _notification: NotificationService,
   ) {
-    this.deviceForm = this.formBuilder.group({
+    this.deviceForm = this._fB.group({
       deviceName: ['', Validators.required],
       deviceType: ['', Validators.required],
       ipAddressType: ['v4', Validators.required],
@@ -434,21 +431,21 @@
 
     let rawPayload = new FormData();
     rawPayload.set('post_data', JSON.stringify(payload));
-    this.deviceService.addDevice(rawPayload)
+    this._device.addDevice(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
           if (result && result.length > 1) {
             if (result[0]) {
-              this.notification.showSuccess(`${payload?.name} added successfully!`);
+              this._notification.showSuccess(`${payload?.name} added successfully!`);
               this.dialogRef.close(true);
             } else {
-              this.notification.showError(`Failed to add device: ${result[1]}`);
+              this._notification.showError(`Failed to add device: ${result[1]}`);
             }
           }
         },
         error: () => {
-          this.notification.showError('Creation Failed.');
+          this._notification.showError('Creation Failed.');
         }
       })
 
@@ -545,8 +542,8 @@
   readonly dialogRef = inject(MatDialogRef<DeviceUpdateLicenseDialog>);
   deviceLicenseForm: FormGroup;
 
-  constructor(private formBuilder: FormBuilder, private deviceService: DeviceService, private notification: NotificationService) {
-    this.deviceLicenseForm = this.formBuilder.group({
+  constructor(private _fB: FormBuilder, private _device: DeviceService, private _notification: NotificationService) {
+    this.deviceLicenseForm = this._fB.group({
       licenseKey: ['', Validators.required],
     })
   }
@@ -559,23 +556,26 @@
     }
     let rawPayload = new FormData();
     rawPayload.set('action', 'Activate');
-    rawPayload.set('options', JSON.stringify({"__pk_list": [JSON.stringify(payload)], license_name: this.deviceLicenseForm.value.licenseKey}));
+    rawPayload.set('options', JSON.stringify({
+      "__pk_list": [JSON.stringify(payload)],
+      license_name: this.deviceLicenseForm.value.licenseKey
+    }));
 
-    this.deviceService.updateDeviceLicense(rawPayload)
+    this._device.updateDeviceLicense(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
           if (result && result.length > 1) {
             if (result[0]) {
-              this.notification.showSuccess(`${this.data?.name} updated successfully!`);
+              this._notification.showSuccess(`${this.data?.name} updated successfully!`);
               this.dialogRef.close(true);
             } else {
-              this.notification.showError(`Failed to update device: ${result[1]}`);
+              this._notification.showError(`Failed to update device: ${result[1]}`);
             }
           }
         },
         error: () => {
-          this.notification.showError('Update Failed.');
+          this._notification.showError('Update Failed.');
         }
       })
   }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/host/host.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/host/host.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/host/host.html	(working copy)
@@ -1,35 +1,37 @@
-<div>
-  <form
-    (ngSubmit)="onSubmit()"
-    [formGroup]="hostForm"
-    class="common-form"
-  >
-    <div class="form-field-wrapper">
-      <label for="hostName" class="form-label">Hostname</label>
-      <mat-form-field appearance="outline" subscriptSizing="dynamic">
-        <input
-          id="hostName"
-          formControlName="hostName"
-          matInput
-          placeholder="Hostname"
-          type="text"
-        />
-        @if (hostForm.get('hostName')?.invalid && hostForm.get('hostName')?.touched) {
-          <mat-error>
-            @if (hostForm.get('hostName')?.errors?.['required']) {
-              Hostname port is required.
-            } @else {
-              Invalid hostname format.
-            }
-          </mat-error>
-        }
-      </mat-form-field>
-    </div>
-    <button
-      type="submit"
-      mat-raised-button
-      color="primary">
-      Submit
-    </button>
-  </form>
-</div>
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-content>
+    <form
+      (ngSubmit)="onSubmit()"
+      [formGroup]="hostForm"
+      class="common-form"
+    >
+      <div class="form-field-wrapper">
+        <label for="hostName" class="form-label">Hostname</label>
+        <mat-form-field appearance="outline" subscriptSizing="dynamic">
+          <input
+            id="hostName"
+            formControlName="hostName"
+            matInput
+            placeholder="Hostname"
+            type="text"
+          />
+          @if (hostForm.get('hostName')?.invalid && hostForm.get('hostName')?.touched) {
+            <mat-error>
+              @if (hostForm.get('hostName')?.errors?.['required']) {
+                Hostname port is required.
+              } @else {
+                Invalid hostname format.
+              }
+            </mat-error>
+          }
+        </mat-form-field>
+      </div>
+      <button
+        type="submit"
+        mat-raised-button
+        color="primary">
+        Submit
+      </button>
+    </form>
+  </mat-card-content>
+</mat-card>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/host/host.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/host/host.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/host/host.scss	(working copy)
@@ -0,0 +1,22 @@
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
+
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/license/license.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/license/license.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/license/license.html	(working copy)
@@ -1,7 +1,4 @@
 <mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <mat-card-title>License Information</mat-card-title>
-  </mat-card-header>
   <mat-card-content>
     <div class="dialog-container">
       <button mat-raised-button color="basic" (click)="updateLicense()" class="end-item">Update License</button>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/license/license.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/license/license.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/license/license.scss	(working copy)
@@ -3,7 +3,19 @@
   border-radius: 0;
   background-color: inherit;
   font-size: 14px !important;
+
   mat-card-header {
     color: #1170cf;
   }
 }
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.html	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.html	(working copy)
@@ -0,0 +1,171 @@
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-header>
+    <mat-card-title>
+      <a class="back-to-main-page" (click)="navigateToLogAnalysis()">
+        <fa-icon [icon]="['far', 'circle-left']"></fa-icon>
+        Log Analysis
+      </a>
+    </mat-card-title>
+  </mat-card-header>
+</mat-card>
+<div class="table-container">
+  <form (ngSubmit)="updateLogFilters()" [formGroup]="searchForm" class="filter-row">
+    <div class="form-field-wrapper">
+      <label for="filter" class="form-label-1">Filter</label>
+      <mat-form-field appearance="outline" subscriptSizing="dynamic">
+        <input
+          id="filter"
+          formControlName="filter"
+          matInput
+          placeholder="response_code=200"
+          type="text"
+        />
+      </mat-form-field>
+    </div>
+
+    <div class="form-field-wrapper">
+      <label for="start" class="form-label-1">Start</label>
+      <mat-form-field appearance="outline" subscriptSizing="dynamic">
+        <input
+          matInput
+          [ngxMatDatetimePicker]="startDatePicker"
+          placeholder="2025-01-01 00:00:00"
+          formControlName="start"
+        />
+        <ngx-mat-datepicker-toggle
+          matSuffix
+          [for]="startDatePicker"
+        ></ngx-mat-datepicker-toggle>
+        <ngx-mat-datetime-picker
+          #startDatePicker
+          [showSpinners]="true"
+          [showSeconds]="true"
+          [touchUi]="false"
+          [stepHour]="1"
+          [stepMinute]="1"
+          [stepSecond]="1"
+          [disableMinute]="false"
+        >
+          <mat-icon
+            ngxMatDatetimePickerToday
+            (click)="startDatePicker.close()"
+          >today
+          </mat-icon>
+        </ngx-mat-datetime-picker>
+      </mat-form-field>
+    </div>
+
+    <div class="form-field-wrapper">
+      <label for="end" class="form-label-1">End</label>
+      <mat-form-field appearance="outline" subscriptSizing="dynamic">
+        <input
+          matInput
+          [ngxMatDatetimePicker]="endDatePicker"
+          placeholder="2025-01-01 00:00:00"
+          formControlName="end"
+        />
+        <ngx-mat-datepicker-toggle
+          matSuffix
+          [for]="endDatePicker"
+        ></ngx-mat-datepicker-toggle>
+        <ngx-mat-datetime-picker
+          #endDatePicker
+          [showSpinners]="true"
+          [showSeconds]="true"
+          [touchUi]="false"
+          [stepHour]="1"
+          [stepMinute]="1"
+          [stepSecond]="1"
+          [disableMinute]="false"
+        >
+          <mat-icon
+            ngxMatDatetimePickerToday
+            (click)="endDatePicker.close()"
+          >today
+          </mat-icon>
+        </ngx-mat-datetime-picker>
+      </mat-form-field>
+    </div>
+    <button mat-raised-button color="primary" type="submit">Search</button>
+  </form>
+  <div>
+    <b>Example</b>
+    <ul>
+      <li><span (click)="setFilterText('http_status_code=200')" class="a-link-color">http_status_code=200(200/400/401/403/404/500/504...)</span>
+      </li>
+      <li><span (click)="setFilterText('http_method=GET')" class="a-link-color">http_method=GET(GET/POST/PUT...)</span></li>
+      <li><span (click)="setFilterText('http_method=GET&http_status_code=200')" class="a-link-color">http_method=GET&http_status_code=200</span>
+      </li>
+      <li><span (click)="setFilterText('virtual_ip=10.1.1.1')" class="a-link-color">virtual_ip=10.1.1.1</span></li>
+    </ul>
+  </div>
+  @if (totalRecordPoints > 0) {
+    <mat-grid-list cols="3" rowHeight="100px">
+      <mat-grid-tile colspan="3" rowspan="3">
+        <mat-card class="dashboard-card" appearance="outlined">
+          <mat-card-content class="card-content-wrapper">
+            <div class="card-header-row">
+              <mat-card-title class="card-title">
+                <span class="card-title-text">Total Records - {{ totalRecordPoints }}</span>
+              </mat-card-title>
+            </div>
+            <div class="chart-flex-container">
+              <div echarts [options]="chartOption1" (chartClick)="onChartClick($event)" class="chart-container"></div>
+            </div>
+          </mat-card-content>
+        </mat-card>
+      </mat-grid-tile>
+    </mat-grid-list>
+  }
+  <mat-card class="page-card-1" appearance="filled">
+    <mat-card-content>
+      <div class="table-container">
+        <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
+          <ng-container matColumnDef="serial">
+            <th mat-header-cell *matHeaderCellDef> No.</th>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+          </ng-container>
+          <ng-container matColumnDef="timestamp">
+            <th mat-header-cell *matHeaderCellDef> Timestamp</th>
+            <td mat-cell *matCellDef="let element">{{ element?.timestamp | date: 'medium' }}</td>
+          </ng-container>
+          <ng-container matColumnDef="srcIp">
+            <th mat-header-cell *matHeaderCellDef> Source IP</th>
+            <td mat-cell *matCellDef="let element">{{ element?.client_ip }}</td>
+          </ng-container>
+          <ng-container matColumnDef="useragent">
+            <th mat-header-cell *matHeaderCellDef> User Agent</th>
+            <td mat-cell *matCellDef="let element">{{ element?.useragent?.device?.name +', '+ element?.useragent?.os?.full +', '+ element?.useragent?.name +', '+ element?.useragent?.version }}</td>
+          </ng-container>
+          <ng-container matColumnDef="method">
+            <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Method</th>
+            <td mat-cell *matCellDef="let element">{{ element?.http_method }}</td>
+          </ng-container>
+          <ng-container matColumnDef="serverIp">
+            <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Server IP</th>
+            <td mat-cell *matCellDef="let element">{{ element?.virtual_ip }}</td>
+          </ng-container>
+          <ng-container matColumnDef="statusCode">
+            <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Status Code</th>
+            <td mat-cell *matCellDef="let element">{{ element?.http_status_code }}</td>
+          </ng-container>
+          <ng-container matColumnDef="rtt">
+            <th mat-header-cell *matHeaderCellDef class="action-header w-10"> RTT</th>
+            <td mat-cell *matCellDef="let element">{{ element?.duration }}</td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="dataColumns"></tr>
+          <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="8">No results found.</td>
+          </tr>
+        </table>
+        <mat-paginator
+          [length]="totalRecords"
+          [pageSize]="10"
+          showFirstLastButtons
+        >
+        </mat-paginator>
+      </div>
+    </mat-card-content>
+  </mat-card>
+</div>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.scss	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.scss	(working copy)
@@ -0,0 +1,239 @@
+.filter-row {
+  display: flex;
+  gap: 15px;
+  flex-wrap: wrap;
+  margin-top: 15px;
+  align-items: center;
+
+  .filter-field {
+    min-width: 180px;
+    flex: 1;
+  }
+}
+
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
+
+.dashboard-card {
+  width: 100%;
+  height: 100%;
+  border-radius: 8px;
+  background-color: inherit;
+}
+
+.card-content-wrapper {
+  margin-top: 2px;
+  padding: 0 !important;
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  width: 100%;
+}
+
+.card-header-row {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  margin-bottom: 8px;
+  padding: 0 8px;
+}
+
+.card-header-row-1 {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  margin-bottom: 0;
+  padding: 0 4px;
+}
+
+.metric-icon {
+  color: #3f51b5;
+}
+
+.card-title {
+  font-size: 14px;
+  font-weight: 500;
+  color: #555;
+  margin: 0;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+}
+
+.card-title-1 {
+  font-size: 12px;
+  font-weight: 400;
+  color: #555;
+  margin: 0;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  width: 100%;
+}
+
+.metric-value {
+  display: flex;
+  justify-content: center;
+  align-items: flex-end;
+  line-height: 1;
+}
+
+.metric-label {
+  display: flex;
+  justify-content: center;
+  align-items: flex-end;
+  font-size: 0.9rem;
+  color: #777;
+  margin-top: 5px;
+}
+
+.online-count {
+  font-size: 36px;
+  font-weight: 600;
+  color: #333;
+}
+
+.total-count {
+  font-size: 18px;
+  font-weight: 500;
+  color: #888;
+  margin-left: 4px;
+}
+
+.status-details {
+  font-size: 14px;
+  color: #d32f2f;
+  margin: 0;
+  font-weight: 500;
+  text-align: center;
+}
+
+.active,
+.matrics-icon {
+  color: darkgreen;
+}
+
+.chart-flex-container {
+  display: flex;
+  justify-content: space-around;
+  align-items: center;
+  height: 100%;
+  width: 100%;
+  flex-grow: 1;
+}
+
+.chart-flex-container-2 {
+
+}
+
+.small-table{
+  .mat-mdc-table {
+    background-color: transparent;
+  }
+  .mat-mdc-row {
+    height: 30px;
+  }
+}
+
+.chart-container {
+  width: 100%;
+  height: 100%;
+  max-width: none;
+  max-height: none;
+}
+
+.chart-flex-container .chart-container {
+  width: 100%;
+  height: 100%;
+}
+
+mat-grid-list {
+  height: 100%;
+  width: 100%;
+}
+
+.metrics-container {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  gap: 20px;
+}
+
+.card-body-content {
+  flex-grow: 1;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+.metrics-horizontal-container {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  gap: 20px;
+  width: 100%;
+}
+
+.metric-item {
+  text-align: center;
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+}
+
+.metric-value {
+  font-size: 1rem;
+  font-weight: 500;
+  color: #333;
+}
+
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
+
+.submit-button-wrapper {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+}
+
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.spec.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.spec.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.spec.ts	(working copy)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LogAnalysisSlbElaborate } from './log-analysis-slb-elaborate';
+
+describe('LogAnalysisSlbElaborate', () => {
+  let component: LogAnalysisSlbElaborate;
+  let fixture: ComponentFixture<LogAnalysisSlbElaborate>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [LogAnalysisSlbElaborate]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(LogAnalysisSlbElaborate);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-elaborate/log-analysis-slb-elaborate.ts	(working copy)
@@ -0,0 +1,349 @@
+import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
+import {SharedModule} from '../../../shared/shared-module';
+import {ActivatedRoute, Router} from '@angular/router';
+import {FormBuilder, FormControl, FormGroup} from '@angular/forms';
+import {NgxMatDatepickerToggle} from '@ngxmc/datetime-picker';
+import {OpenSearch} from '../../../services/open-search';
+import {take} from 'rxjs/operators';
+import {NotificationService} from '../../../services/notification';
+import {EChartsOption} from 'echarts';
+import {MatTableDataSource} from '@angular/material/table';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
+import {MatPaginator, PageEvent} from '@angular/material/paginator';
+
+@Component({
+  selector: 'app-log-analysis-slb-elaborate',
+  imports: [SharedModule, NgxMatDatepickerToggle, GlobalSerialPipe],
+  templateUrl: './log-analysis-slb-elaborate.html',
+  styleUrl: './log-analysis-slb-elaborate.scss'
+})
+export class LogAnalysisSlbElaborate implements OnInit, AfterViewInit {
+
+  serviceName: string = '';
+  vip: string = '';
+  searchForm!: FormGroup;
+
+  endTimeMillis!: number;
+  startTimeMillis!: number;
+
+  chartOption1: EChartsOption = {};
+
+  dataSource: MatTableDataSource<any> = new MatTableDataSource();
+  dataColumns: Array<string> = ['serial', 'timestamp', 'srcIp', 'useragent', 'method', 'serverIp', 'statusCode', 'rtt'];
+  totalRecords = 0;
+  @ViewChild(MatPaginator) paginator!: MatPaginator;
+
+  constructor(
+    private _route: ActivatedRoute,
+    private _fB: FormBuilder,
+    private _opensearch: OpenSearch,
+    private _notification: NotificationService,
+    private _router: Router
+  ) {
+    this.getCurrentTime();
+  }
+
+  ngOnInit() {
+    this.serviceName = this._route.snapshot.paramMap.get('serviceName') || '';
+    this.vip = this._route.snapshot.paramMap.get('vip') || '';
+
+    this.searchForm = this._fB.group({
+      serviceName: [this.serviceName],
+      filter: [''],
+      start: new FormControl(null),
+      end: new FormControl(null)
+    });
+    setTimeout(() => {
+      let payload: any = {
+        "size": 0,
+        "query": {
+          "constant_score": {
+            "filter": {
+              "bool": {
+                "must": [
+                  {
+                    "term": {
+                      "virtual_ip": this.vip
+                    }
+                  },
+                  {
+                    "range": {
+                      "@timestamp": {
+                        "gte": this.startTimeMillis,
+                        "lte": this.endTimeMillis
+                      }
+                    }
+                  }
+                ]
+              }
+            }
+          }
+        },
+        "aggs": {
+          "log_over_time": {
+            "date_histogram": {
+              "field": "@timestamp",
+              "interval": "5m",
+              "format": "yyyy-MM-dd HH:mm:ss"
+            }
+          }
+        }
+      };
+      this.searchForm.patchValue({
+        start: new Date(this.startTimeMillis),
+        end: new Date(this.endTimeMillis),
+      })
+      this.getFilteredLogs(payload);
+    })
+  }
+
+  getCurrentTime(): void {
+    const now = new Date();
+    this.endTimeMillis = now.getTime();
+
+    // Calculate the time 15 minutes ago
+    const fifteenMinutesInMilliseconds = 15 * 60 * 1000;
+    const timeMinus15Minutes = new Date(this.endTimeMillis - fifteenMinutesInMilliseconds);
+    this.startTimeMillis = timeMinus15Minutes.getTime();
+  }
+
+  totalRecordPoints: number = 0;
+
+  getFilteredLogs(payload: any) {
+    this.totalRecordPoints = 0;
+
+    this._opensearch.queryOSLogs(payload).pipe(take(1)).subscribe({
+      next: (result: any) => {
+        if (result && result?.aggregations && result.aggregations?.log_over_time && result.aggregations.log_over_time?.buckets) {
+          let buckets = result.aggregations.log_over_time?.buckets;
+          if (buckets.length > 0) {
+            this.totalRecordPoints = buckets?.length;
+            this.updateChart(buckets);
+          }
+        }
+      },
+      error: (error: any) => {
+        this._notification.showError(`Error: ${error?.message || 'Failed to fetch the logs'}`);
+      }
+    });
+  }
+
+  updateChart(_data: any) {
+    const transformedData = _data.map((item: any) => [
+      item.key_as_string + 'Z',
+      item.doc_count
+    ]);
+
+    const firstTimestamp = _data[0].key;
+    const lastTimestamp = _data[_data.length - 1].key;
+
+    const bufferMilliseconds = 5 * 60 * 1000;
+
+    this.chartOption1 = {
+      tooltip: {
+        trigger: 'axis',
+        formatter: (params: any) => {
+          const data = params[0].data;
+          const localTime = new Intl.DateTimeFormat('en-US', {
+            hour: '2-digit', minute: '2-digit', second: '2-digit'
+          }).format(new Date(data[0]));
+
+          const count = data[1];
+          return `Time (Local): ${localTime}<br/>Docs Count: ${count}`;
+        }
+      },
+      xAxis: {
+        type: 'time',
+        min: firstTimestamp - bufferMilliseconds,
+        max: lastTimestamp + bufferMilliseconds,
+        axisLabel: {
+          formatter: (value: number) => {
+            const date = new Date(value);
+            return new Intl.DateTimeFormat('en-US', {
+              hour: '2-digit', minute: '2-digit', second: '2-digit', hour12: false
+            }).format(date);
+          }
+        }
+      },
+      yAxis: {
+        type: 'value',
+        name: 'Docs Count',
+        axisLabel: {
+          formatter: '{value}'
+        }
+      },
+      series: [
+        {
+          name: 'Docs Count over Time',
+          data: transformedData,
+          type: 'line',
+          smooth: true,
+          lineStyle: {
+            width: 2
+          },
+          symbol: 'circle',
+          symbolSize: 8
+        }
+      ],
+    };
+  }
+
+  tableStartTime: any = '';
+  tableEndTime: any = '';
+
+  onChartClick(params: any): void {
+    if (params.componentType === 'series') {
+      let start = new Date(params.value[0]);
+      let end = new Date(start);
+      end.setUTCHours(end.getUTCHours() + 1);
+      this.tableStartTime = start.getTime();
+      this.tableEndTime = end.getTime();
+    }
+    this.updateDataTable();
+  }
+
+  private readonly keywordFields = new Set<string>([
+    'http_method',
+  ]);
+
+  updateLogFilters() {
+    this.dataSource.data = [];
+    this.startTimeMillis = new Date(this.searchForm.value?.start).getTime();
+    this.endTimeMillis = new Date(this.searchForm.value?.end).getTime();
+    let _filters: any = [
+      {
+        "term": {
+          "virtual_ip": this.vip
+        }
+      },
+      {
+        "range": {
+          "@timestamp": {
+            "gte": this.startTimeMillis,
+            "lte": this.endTimeMillis
+          }
+        }
+      }
+    ]
+    let _keyword = this.searchForm.value?.filter;
+    _keyword = _keyword.split('&');
+    _keyword?.forEach((item: any) => {
+      let _term = item.split('=');
+      if (_term.length > 1) {
+        let x = { 'term': {} };
+        if (this.keywordFields.has(_term[0])) {
+          x['term'] = {[_term[0] + '.keyword']: _term[1]}
+        } else {
+          x['term'] = {[_term[0]]: _term[1]}
+        }
+        _filters.push(x);
+      }
+    })
+    let payload: any = {
+      "size": 0,
+      "query": {
+        "constant_score": {
+          "filter": {
+            "bool": {
+              "must": _filters
+            }
+          }
+        }
+      },
+      "aggs": {
+        "log_over_time": {
+          "date_histogram": {
+            "field": "@timestamp",
+            "interval": "5m",
+            "format": "yyyy-MM-dd HH:mm:ss"
+          }
+        }
+      }
+    };
+    this.getFilteredLogs(payload);
+  }
+
+  pageStart: number = 0;
+  pageSize: number = 10;
+  updateDataTable() {
+    let payload: any = {
+      "size": this.pageSize,
+      "from": this.pageStart,
+      "sort": [{"@timestamp": {"order": "desc", "unmapped_type": "boolean"}}],
+      "_source": ["client_ip", "http_status_code", "http_method", "virtual_ip", "duration", "useragent"],
+      "query": {
+        "constant_score": {
+          "filter": {
+            "bool": {
+              "must": [{"term": {"virtual_ip": this.vip}}, {
+                "range": {
+                  "@timestamp": {
+                    "gte": this.tableStartTime,
+                    "lte": this.tableEndTime,
+                  }
+                }
+              }]
+            }
+          }
+        }
+      }
+    }
+    this._opensearch.queryOSLogs(payload).pipe(take(1)).subscribe({
+      next: (result: any) => {
+        if (result && result?.hits && result?.hits?.hits) {
+          let _hits: any = result?.hits?.hits;
+          let newData: any[] = [];
+          _hits?.forEach((item: any) => {
+            let _source = item?._source;
+            let _timestamp = item?.sort.length > 0 ? new Date(item?.sort[0]) : null;
+            newData.push({
+              timestamp: _timestamp,
+              client_ip: _source?.client_ip,
+              http_status_code: _source?.http_status_code,
+              http_method: _source?.http_method,
+              virtual_ip: _source?.virtual_ip,
+              duration: _source?.duration,
+              useragent: _source?.useragent
+            })
+          })
+          this.totalRecords = result?.hits?.total?.value;
+          if (this.paginator) {
+            this.paginator.length = result?.hits?.total?.value;
+            this.paginator.pageIndex = Math.floor(payload?.start / payload?.size);
+            this.paginator.pageSize = payload?.size || 10;
+          }
+          this.dataSource.data = newData;
+          this.dataSource.paginator = this.paginator;
+        }
+      },
+      error: (error: any) => {
+        this._notification.showError(`Error: ${error?.message || 'Failed to fetch the logs'}`);
+        this.totalRecords = 0;
+        if (this.paginator) {
+          this.paginator.length = 0;
+          this.paginator.pageIndex = 0;
+        }
+      }
+    });
+  }
+
+  ngAfterViewInit() {
+    this.paginator.page.subscribe((event: PageEvent) => {
+      this.pageStart = event.pageIndex * event.pageSize;
+      this.pageSize = event.pageSize;
+      if (this.totalRecords !== 0) {
+        this.updateDataTable();
+      }
+    });
+  }
+
+  setFilterText(filterText: string) {
+    this.searchForm.patchValue({
+      filter: filterText,
+    })
+  }
+
+  navigateToLogAnalysis() {
+    this._router.navigate(['/log-analysis']);
+  }
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.html	(working copy)
@@ -1 +1,49 @@
-<p>log-analysis-slb-overview works!</p>
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-content>
+    <div class="table-container">
+      <div class="mat-elevation-z0">
+        <table mat-table [dataSource]="dataSource">
+          <ng-container matColumnDef="serial">
+            <th mat-header-cell *matHeaderCellDef>ID</th>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+          </ng-container>
+          <ng-container matColumnDef="serviceName">
+            <th mat-header-cell *matHeaderCellDef>Service Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="details-page-link" (click)="goToDetails(element)">{{ element?.service_name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="serviceType">
+            <th mat-header-cell *matHeaderCellDef>Service Type</th>
+            <td mat-cell *matCellDef="let element">{{ element?.protocol | uppercase }}</td>
+          </ng-container>
+          <ng-container matColumnDef="ip">
+            <th mat-header-cell *matHeaderCellDef>IP Address</th>
+            <td mat-cell *matCellDef="let element">{{ element?.vip }}</td>
+          </ng-container>
+          <ng-container matColumnDef="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Device Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="details-page-link" (click)="goToDeviceDetails(element)">{{ element?.device_name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceGroup">
+            <th mat-header-cell *matHeaderCellDef>Device Group</th>
+            <td mat-cell *matCellDef="let element">{{ element?.device_group }}</td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="dataColumns"></tr>
+          <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="11">No results found.</td>
+          </tr>
+        </table>
+        <mat-paginator
+          [length]="totalRecords"
+          [pageSize]="10"
+          [pageSizeOptions]="[10, 20, 50]"
+        >
+        </mat-paginator>
+      </div>
+    </div>
+  </mat-card-content>
+</mat-card>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.scss	(working copy)
@@ -0,0 +1,21 @@
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-analysis-slb-overview/log-analysis-slb-overview.ts	(working copy)
@@ -1,11 +1,101 @@
-import { Component } from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {take} from 'rxjs/operators';
+import {
+  MatTableDataSource
+} from '@angular/material/table';
+import {MatPaginator} from '@angular/material/paginator';
+import {DeviceService} from '../../../services/device-service';
+import {NotificationService} from '../../../services/notification';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
+import {SharedModule} from '../../../shared/shared-module';
+import {Router} from '@angular/router';
 
 @Component({
   selector: 'app-log-analysis-slb-overview',
-  imports: [],
+  imports: [
+    GlobalSerialPipe, SharedModule
+  ],
   templateUrl: './log-analysis-slb-overview.html',
   styleUrl: './log-analysis-slb-overview.scss'
 })
-export class LogAnalysisSlbOverview {
+export class LogAnalysisSlbOverview implements OnInit {
 
+  devices: any = [];
+  groups: any = [];
+  totalRecords: number = 0;
+  dataSource: MatTableDataSource<any> = new MatTableDataSource();
+  dataColumns: string[] = ['serial', 'serviceName', 'serviceType', 'ip', 'deviceName', 'deviceGroup'];
+  @ViewChild(MatPaginator) paginator!: MatPaginator;
+
+  constructor(
+    private _device: DeviceService,
+    private _notification: NotificationService,
+    private _router: Router,
+  ) {
+  }
+
+  ngOnInit() {
+    this.getDeviceGroups();
+  }
+
+  getDeviceGroups(): void {
+    this.devices = [];
+    this.groups = [];
+    // ToDo: Update with actual RoleId
+    let roleId = "0"
+    let rawPayload = new FormData();
+    rawPayload.set('action', 'FilterRoleDeviceGroups');
+    rawPayload.set('options', JSON.stringify({"role_id": roleId}));
+    this._device.getDeviceGroups(rawPayload)
+      .pipe(take(1))
+      .subscribe({
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            if (result[1] && 'result' in result[1]) {
+              let groups = result[1].result;
+              groups.forEach((group: any) => {
+                this.groups.push(group?.group_name);
+                group?.device_list.forEach((device: any) => {
+                  this.devices.push(device);
+                  if (device?.type.toLowerCase() === 'apv' || device?.type.toLowerCase() === 'vapv') {
+                    this.getAPVVirtualServices(device);
+                  }
+                })
+              })
+            }
+          }
+        }, error: (error: { message: string; }) => {
+          console.log(error);
+          this._notification.showError(error.message);
+        }
+      })
+  }
+
+  getAPVVirtualServices(_device: any) {
+    this._device.getAPVSLBVirtualServices(_device?.id).pipe(take(1)).subscribe({
+      next: (result: any) => {
+        if (result && result.VirtualService) {
+          result.VirtualService?.forEach((_service: any) => {
+            _service['device_name'] = _device?.name;
+            _service['device_group'] = _device?.device_group;
+            this.dataSource.data.push(_service);
+          })
+
+        }
+        this.dataSource.paginator = this.paginator;
+        this.totalRecords = this.dataSource.data.length;
+      },
+      error: error => {
+        this._notification.showError(`Error: ${error?.message}`);
+      }
+    })
+  }
+
+  goToDetails(_service: any) {
+    this._router.navigate(['/log-analysis/elaborate', _service?.service_name, _service?.vip]);
+  }
+
+  goToDeviceDetails(_service: any) {
+    this._router.navigate(['/inventory/devices']);
+  }
 }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-settings/log-settings.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-settings/log-settings.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-settings/log-settings.html	(working copy)
@@ -1,90 +1,96 @@
-<div>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>Log Settings</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <form
-        (ngSubmit)="updateSystemHostConfig()"
-        [formGroup]="logSettingsForm"
-        class="common-form"
-      >
-        <div class="form-field-wrapper">
-          <label for="enable_log" class="form-label">Enable Log</label>
-          <mat-slide-toggle formControlName="enable_log"></mat-slide-toggle>
-        </div>
+<mat-tab-group mat-stretch-tabs="false" animationDuration="0ms">
+  <mat-tab label="Log Settings">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <form
+              (ngSubmit)="updateSystemHostConfig()"
+              [formGroup]="logSettingsForm"
+              class="common-form"
+            >
+              <div class="form-field-wrapper">
+                <label for="enable_log" class="form-label">Enable Log</label>
+                <mat-slide-toggle formControlName="enable_log"></mat-slide-toggle>
+              </div>
 
-        <div class="form-field-wrapper">
-          <label for="log_level" class="form-label">Log Level</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <mat-select formControlName="log_level">
-              @for (_level of levels; track _level) {
-                <mat-option [value]="_level.value">{{ _level.displayName }}</mat-option>
-              }
-            </mat-select>
-            @if (logSettingsForm.get('groupName')?.invalid && logSettingsForm.get('groupName')?.touched) {
-              <mat-error>
-                @if (logSettingsForm.get('groupName')?.errors?.['required']) {
-                  Group name is required.
-                } @else {
-                  Invalid group name format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
+              <div class="form-field-wrapper">
+                <label for="log_level" class="form-label">Log Level</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <mat-select formControlName="log_level">
+                    @for (_level of levels; track _level) {
+                      <mat-option [value]="_level.value">{{ _level.displayName }}</mat-option>
+                    }
+                  </mat-select>
+                  @if (logSettingsForm.get('groupName')?.invalid && logSettingsForm.get('groupName')?.touched) {
+                    <mat-error>
+                      @if (logSettingsForm.get('groupName')?.errors?.['required']) {
+                        Group name is required.
+                      } @else {
+                        Invalid group name format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
 
-        <button
-          type="submit"
-          mat-raised-button
-          color="primary">
-          Submit
-        </button>
-      </form>
-    </mat-card-content>
-  </mat-card>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>Remote Syslog</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <div class="button-container">
-        <button mat-raised-button (click)="addRemoteSyslogHost()">Add</button>
+              <button
+                type="submit"
+                mat-raised-button
+                color="primary">
+                Submit
+              </button>
+            </form>
+          </mat-card-content>
+        </mat-card>
       </div>
-      <div class="table-container">
-        <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
-          <ng-container matColumnDef="serial">
-            <th mat-header-cell *matHeaderCellDef> No.</th>
-            <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
-          </ng-container>
-          <ng-container matColumnDef="ip">
-            <th mat-header-cell *matHeaderCellDef> IP Address</th>
-            <td mat-cell *matCellDef="let element"> {{ element.host_ip }}</td>
-          </ng-container>
-          <ng-container matColumnDef="port">
-            <th mat-header-cell *matHeaderCellDef> Port</th>
-            <td mat-cell *matCellDef="let element"> {{ element.port }}</td>
-          </ng-container>
-          <ng-container matColumnDef="protocol">
-            <th mat-header-cell *matHeaderCellDef> Protocol</th>
-            <td mat-cell *matCellDef="let element"> {{ protocols[element.protocol] }}</td>
-          </ng-container>
-          <ng-container matColumnDef="action">
-            <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
-            <td mat-cell *matCellDef="let element">
-              <div class="row-action a-link">
-                <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete Device"
-                         (click)="deleteRemoteSyslogHost(element)"></fa-icon>
-              </div>
-            </td>
-          </ng-container>
-          <tr mat-header-row *matHeaderRowDef="remoteHostColumns"></tr>
-          <tr mat-row *matRowDef="let row; columns: remoteHostColumns;"></tr>
-          <tr class="mat-row table-no-data" *matNoDataRow>
-            <td class="mat-cell" colspan="4">No results found.</td>
-          </tr>
-        </table>
+    </ng-template>
+  </mat-tab>
+  <mat-tab label="Remote Syslog">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <div class="button-container">
+              <button mat-raised-button (click)="addRemoteSyslogHost()">Add</button>
+            </div>
+            <div class="table-container">
+              <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
+                <ng-container matColumnDef="serial">
+                  <th mat-header-cell *matHeaderCellDef> No.</th>
+                  <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
+                </ng-container>
+                <ng-container matColumnDef="ip">
+                  <th mat-header-cell *matHeaderCellDef> IP Address</th>
+                  <td mat-cell *matCellDef="let element"> {{ element.host_ip }}</td>
+                </ng-container>
+                <ng-container matColumnDef="port">
+                  <th mat-header-cell *matHeaderCellDef> Port</th>
+                  <td mat-cell *matCellDef="let element"> {{ element.port }}</td>
+                </ng-container>
+                <ng-container matColumnDef="protocol">
+                  <th mat-header-cell *matHeaderCellDef> Protocol</th>
+                  <td mat-cell *matCellDef="let element"> {{ protocols[element.protocol] }}</td>
+                </ng-container>
+                <ng-container matColumnDef="action">
+                  <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
+                  <td mat-cell *matCellDef="let element">
+                    <div class="row-action a-link">
+                      <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete Device"
+                               (click)="deleteRemoteSyslogHost(element)"></fa-icon>
+                    </div>
+                  </td>
+                </ng-container>
+                <tr mat-header-row *matHeaderRowDef="remoteHostColumns"></tr>
+                <tr mat-row *matRowDef="let row; columns: remoteHostColumns;"></tr>
+                <tr class="mat-row table-no-data" *matNoDataRow>
+                  <td class="mat-cell" colspan="4">No results found.</td>
+                </tr>
+              </table>
+            </div>
+          </mat-card-content>
+        </mat-card>
       </div>
-    </mat-card-content>
-  </mat-card>
-</div>
+    </ng-template>
+  </mat-tab>
+</mat-tab-group>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-settings/log-settings.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-settings/log-settings.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/log-settings/log-settings.scss	(working copy)
@@ -1,15 +1,9 @@
-.page-card {
-  width: 100%;
-  border-radius: 0;
-  background-color: inherit;
-  font-size: 14px !important;
-}
-
 .page-card-1 {
   width: 100%;
   border-radius: 0;
   background-color: inherit;
   font-size: 14px !important;
+
   mat-card-header {
     color: #1170cf;
   }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/network/network.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/network/network.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/network/network.html	(working copy)
@@ -1,140 +1,156 @@
-<div>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>Interfaces</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <div class="table-container">
-        <table mat-table [dataSource]="interfacesDataSource" class="mat-elevation-z1">
-          <ng-container matColumnDef="serial">
-            <th mat-header-cell *matHeaderCellDef> No.</th>
-            <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
-          </ng-container>
-          <ng-container matColumnDef="name">
-            <th mat-header-cell *matHeaderCellDef> Name</th>
-            <td mat-cell *matCellDef="let element">
-              <a class="a-link-color" (click)="showInterfaceInfo(element)">{{ element.interface_name }}</a>
-            </td>
-          </ng-container>
-          <ng-container matColumnDef="ip">
-            <th mat-header-cell *matHeaderCellDef> Interface IP</th>
-            <td mat-cell *matCellDef="let element"> {{ element.addresses[0].ip + " - " + element.addresses[0].mask_prefix }}</td>
-          </ng-container>
-          <ng-container matColumnDef="type">
-            <th mat-header-cell *matHeaderCellDef> Type</th>
-            <td mat-cell *matCellDef="let element"> {{ element.inf_type == 'mgmt' ? 'Management Interface' : element.inf_type }}</td>
-          </ng-container>
-          <ng-container matColumnDef="action">
-            <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
-            <td mat-cell *matCellDef="let element">
-              <div class="row-action a-link">
-                <fa-icon [icon]="['far', 'edit']" size="lg" class="delete-icon" matTooltip="Edit Interface"
-                         (click)="updateNetworkInterface(element)"></fa-icon>
-              </div>
-            </td>
-          </ng-container>
-          <tr mat-header-row *matHeaderRowDef="interfacesColumns"></tr>
-          <tr mat-row *matRowDef="let row; columns: interfacesColumns;"></tr>
-          <tr class="mat-row table-no-data" *matNoDataRow>
-            <td class="mat-cell" colspan="4">No results found.</td>
-          </tr>
-        </table>
+<mat-tab-group mat-stretch-tabs="false" animationDuration="0ms">
+  <mat-tab label="Interfaces">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <div class="table-container">
+              <table mat-table [dataSource]="interfacesDataSource" class="mat-elevation-z1">
+                <ng-container matColumnDef="serial">
+                  <th mat-header-cell *matHeaderCellDef> No.</th>
+                  <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+                </ng-container>
+                <ng-container matColumnDef="name">
+                  <th mat-header-cell *matHeaderCellDef> Name</th>
+                  <td mat-cell *matCellDef="let element">
+                    <a class="a-link-color" (click)="showInterfaceInfo(element)">{{ element.interface_name }}</a>
+                  </td>
+                </ng-container>
+                <ng-container matColumnDef="ip">
+                  <th mat-header-cell *matHeaderCellDef> Interface IP</th>
+                  <td mat-cell
+                      *matCellDef="let element"> {{ element.addresses[0].ip + " - " + element.addresses[0].mask_prefix }}
+                  </td>
+                </ng-container>
+                <ng-container matColumnDef="type">
+                  <th mat-header-cell *matHeaderCellDef> Type</th>
+                  <td mat-cell
+                      *matCellDef="let element"> {{ element.inf_type == 'mgmt' ? 'Management Interface' : element.inf_type }}
+                  </td>
+                </ng-container>
+                <ng-container matColumnDef="action">
+                  <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
+                  <td mat-cell *matCellDef="let element">
+                    <div class="row-action a-link">
+                      <fa-icon [icon]="['far', 'edit']" size="lg" class="delete-icon" matTooltip="Edit Interface"
+                               (click)="updateNetworkInterface(element)"></fa-icon>
+                    </div>
+                  </td>
+                </ng-container>
+                <tr mat-header-row *matHeaderRowDef="interfacesColumns"></tr>
+                <tr mat-row *matRowDef="let row; columns: interfacesColumns;"></tr>
+                <tr class="mat-row table-no-data" *matNoDataRow>
+                  <td class="mat-cell" colspan="4">No results found.</td>
+                </tr>
+              </table>
+            </div>
+          </mat-card-content>
+        </mat-card>
       </div>
-    </mat-card-content>
-  </mat-card>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>DNS</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <div class="button-container">
-        <button mat-raised-button (click)="addDNSServer()">Add</button>
+    </ng-template>
+  </mat-tab>
+  <mat-tab label="DNS">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <div class="button-container">
+              <button mat-raised-button (click)="addDNSServer()">Add</button>
+            </div>
+            <div class="table-container">
+              <table mat-table [dataSource]="dnsDataSource" class="mat-elevation-z1">
+                <ng-container matColumnDef="serial">
+                  <th mat-header-cell *matHeaderCellDef> No.</th>
+                  <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+                </ng-container>
+                <ng-container matColumnDef="ip">
+                  <th mat-header-cell *matHeaderCellDef> Interface IP</th>
+                  <td mat-cell *matCellDef="let element"> {{ element.server_ip }}</td>
+                </ng-container>
+                <ng-container matColumnDef="action">
+                  <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
+                  <td mat-cell *matCellDef="let element">
+                    <div class="row-action a-link">
+                      <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete Server"
+                               (click)="deleteDNSServer(element)"></fa-icon>
+                    </div>
+                  </td>
+                </ng-container>
+                <tr mat-header-row *matHeaderRowDef="dnsColumns"></tr>
+                <tr mat-row *matRowDef="let row; columns: dnsColumns;"></tr>
+                <tr class="mat-row table-no-data" *matNoDataRow>
+                  <td class="mat-cell" colspan="4">No results found.</td>
+                </tr>
+              </table>
+            </div>
+          </mat-card-content>
+        </mat-card>
       </div>
-      <div class="table-container">
-        <table mat-table [dataSource]="dnsDataSource" class="mat-elevation-z1">
-          <ng-container matColumnDef="serial">
-            <th mat-header-cell *matHeaderCellDef> No.</th>
-            <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
-          </ng-container>
-          <ng-container matColumnDef="ip">
-            <th mat-header-cell *matHeaderCellDef> Interface IP</th>
-            <td mat-cell *matCellDef="let element"> {{ element.server_ip }}</td>
-          </ng-container>
-          <ng-container matColumnDef="action">
-            <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
-            <td mat-cell *matCellDef="let element">
-              <div class="row-action a-link">
-                <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete Server"
-                         (click)="deleteDNSServer(element)"></fa-icon>
+    </ng-template>
+  </mat-tab>
+  <mat-tab label="Default Route">
+    <ng-template matTabContent>
+      <div class="tab-content">
+        <mat-card class="page-card-1" appearance="filled">
+          <mat-card-content>
+            <form
+              (ngSubmit)="updateDefaultRoute()"
+              [formGroup]="routeForm"
+              class="common-form"
+            >
+              <div class="form-field-wrapper">
+                <label for="ipv4" class="form-label">Gateway IP (IPv4)</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="ipv4"
+                    formControlName="ipv4"
+                    matInput
+                    placeholder="Gateway IP (IPv4)"
+                    type="text"
+                  />
+                  @if (routeForm.get('ipv4')?.invalid && routeForm.get('ipv4')?.touched) {
+                    <mat-error>
+                      @if (routeForm.get('ipv4')?.errors?.['required']) {
+                        IPv4 address is required.
+                      } @else if (routeForm.get('ipv4')?.errors?.['ipv4']) {
+                        Invalid IPv4 address format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
               </div>
-            </td>
-          </ng-container>
-          <tr mat-header-row *matHeaderRowDef="dnsColumns"></tr>
-          <tr mat-row *matRowDef="let row; columns: dnsColumns;"></tr>
-          <tr class="mat-row table-no-data" *matNoDataRow>
-            <td class="mat-cell" colspan="4">No results found.</td>
-          </tr>
-        </table>
+              <div class="form-field-wrapper">
+                <label for="ipv6" class="form-label">Gateway IP (IPv6)</label>
+                <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                  <input
+                    id="ipv6"
+                    formControlName="ipv6"
+                    matInput
+                    placeholder="Gateway IP (IPv6)"
+                    type="text"
+                  />
+                  @if (routeForm.get('ipv6')?.invalid && routeForm.get('ipv6')?.touched) {
+                    <mat-error>
+                      @if (routeForm.get('ipv6')?.errors?.['required']) {
+                        IPv6 address is required.
+                      } @else if (routeForm.get('ipv6')?.errors?.['ipv6']) {
+                        Invalid IPv6 address format.
+                      }
+                    </mat-error>
+                  }
+                </mat-form-field>
+              </div>
+              <div class="button-container-center">
+                <button type="submit" mat-raised-button color="primary">Submit</button> &nbsp;&nbsp;&nbsp;&nbsp;
+                <button type="button" class="warning secondary-btn-center" mat-raised-button
+                        (click)="clearDefaultRoute()">
+                  Clear
+                </button>
+              </div>
+            </form>
+          </mat-card-content>
+        </mat-card>
       </div>
-    </mat-card-content>
-  </mat-card>
-  <mat-card class="page-card-1" appearance="filled">
-    <mat-card-header>
-      <mat-card-title>Default Route</mat-card-title>
-    </mat-card-header>
-    <mat-card-content>
-      <form
-        (ngSubmit)="updateDefaultRoute()"
-        [formGroup]="routeForm"
-        class="common-form"
-      >
-        <div class="form-field-wrapper">
-          <label for="ipv4" class="form-label">Gateway IP (IPv4)</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="ipv4"
-              formControlName="ipv4"
-              matInput
-              placeholder="Gateway IP (IPv4)"
-              type="text"
-            />
-            @if (routeForm.get('ipv4')?.invalid && routeForm.get('ipv4')?.touched) {
-              <mat-error>
-                @if (routeForm.get('ipv4')?.errors?.['required']) {
-                  IPv4 address is required.
-                } @else if (routeForm.get('ipv4')?.errors?.['ipv4']) {
-                  Invalid IPv4 address format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="form-field-wrapper">
-          <label for="ipv6" class="form-label">Gateway IP (IPv6)</label>
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <input
-              id="ipv6"
-              formControlName="ipv6"
-              matInput
-              placeholder="Gateway IP (IPv6)"
-              type="text"
-            />
-            @if (routeForm.get('ipv6')?.invalid && routeForm.get('ipv6')?.touched) {
-              <mat-error>
-                @if (routeForm.get('ipv6')?.errors?.['required']) {
-                  IPv6 address is required.
-                } @else if (routeForm.get('ipv6')?.errors?.['ipv6']) {
-                  Invalid IPv6 address format.
-                }
-              </mat-error>
-            }
-          </mat-form-field>
-        </div>
-        <div class="button-container-center">
-          <button type="submit" mat-raised-button color="primary">Submit</button> &nbsp;&nbsp;&nbsp;&nbsp;
-          <button type="button" class="warning secondary-btn-center" mat-raised-button (click)="clearDefaultRoute()">Clear</button>
-        </div>
-      </form>
-    </mat-card-content>
-  </mat-card>
-</div>
+    </ng-template>
+  </mat-tab>
+</mat-tab-group>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/network/network.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/network/network.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/network/network.ts	(working copy)
@@ -8,10 +8,11 @@
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {CustomValidators} from '../../../utils/custom-validators';
 import {Confirmation} from '../../../services/confirmation';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-network',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './network.html',
   styleUrl: './network.scss'
 })
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/notification-channels/notification-channels.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/notification-channels/notification-channels.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/notification-channels/notification-channels.html	(working copy)
@@ -11,7 +11,7 @@
         <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
           <ng-container matColumnDef="serial">
             <th mat-header-cell *matHeaderCellDef> No.</th>
-            <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
           </ng-container>
           <ng-container matColumnDef="name">
             <th mat-header-cell *matHeaderCellDef> Channel Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/notification-channels/notification-channels.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/notification-channels/notification-channels.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/notification-channels/notification-channels.ts	(working copy)
@@ -9,11 +9,13 @@
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {Subject} from 'rxjs';
 import {MatPaginator} from '@angular/material/paginator';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-notification-channels',
   imports: [
     SharedModule,
+    GlobalSerialPipe,
   ],
   templateUrl: './notification-channels.html',
   styleUrl: './notification-channels.scss'
@@ -63,22 +65,10 @@
           this.cdRef.detectChanges();
         }
       })
-  }
-
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
   }
 
   addNotificationChannel(payload: any = {}) {
-    this.dialogConfig.position = {
-      bottom: '0px', right: '0px',
-    }
     this.dialogConfig.disableClose = true;
-    this.dialogConfig.width = '60%';
-    this.dialogConfig.height = '80%';
     this.dialogConfig.data = payload;
     const dialogRef = this.dialog.open(AddNotificationChannelDialog, this.dialogConfig);
     dialogRef.afterClosed().subscribe((isAdded: boolean) => {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.html	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.html	(working copy)
@@ -0,0 +1,26 @@
+<div class="tab-container">
+  <mat-tab-group mat-stretch-tabs="false" animationDuration="0ms" [selectedIndex]="selectedTabIndex"
+                 (selectedTabChange)="onTabChange($event)">
+    <mat-tab label="SLB - Virtual Services">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-resource-monitoring-slb-virtual/>
+        </div>
+      </ng-template>
+    </mat-tab>
+    <mat-tab label="SLB - Real Services">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-resource-monitoring-slb-real/>
+        </div>
+      </ng-template>
+    </mat-tab>
+    <mat-tab label="LLB">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <app-resource-monitoring-llb/>
+        </div>
+      </ng-template>
+    </mat-tab>
+  </mat-tab-group>
+</div>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.scss	(added)
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.scss	(revision 0)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.scss	(revision 0)
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.spec.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.spec.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.spec.ts	(working copy)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ResourceMonitoringApv } from './resource-monitoring-apv';
+
+describe('ResourceMonitoringApv', () => {
+  let component: ResourceMonitoringApv;
+  let fixture: ComponentFixture<ResourceMonitoringApv>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ResourceMonitoringApv]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(ResourceMonitoringApv);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-apv/resource-monitoring-apv.ts	(working copy)
@@ -0,0 +1,58 @@
+import {Component, OnInit} from '@angular/core';
+import {SharedModule} from '../../../shared/shared-module';
+import {ActivatedRoute, Router} from '@angular/router';
+import {MatTabChangeEvent} from '@angular/material/tabs';
+import {ResourceMonitoringLlb} from '../resource-monitoring-llb/resource-monitoring-llb';
+import {ResourceMonitoringSlbVirtual} from '../resource-monitoring-slb-virtual/resource-monitoring-slb-virtual';
+import {ResourceMonitoringSlbReal} from '../resource-monitoring-slb-real/resource-monitoring-slb-real';
+
+@Component({
+  selector: 'app-resource-monitoring-apv',
+  imports: [SharedModule, ResourceMonitoringLlb, ResourceMonitoringSlbVirtual, ResourceMonitoringSlbReal,],
+  templateUrl: './resource-monitoring-apv.html',
+  styleUrl: './resource-monitoring-apv.scss'
+})
+export class ResourceMonitoringApv implements OnInit {
+
+  selectedTabIndex: number = 0;
+  private tabNames: string[] = [
+    'SLB - Virtual Services',
+    'SLB - Real Services',
+    'LLB',
+  ];
+
+  constructor(private _route: ActivatedRoute, private _router: Router) {
+  }
+
+  ngOnInit(): void {
+    this._route.queryParams.subscribe(params => {
+      const tabParam = params['subTab'];
+      if (tabParam) {
+        const index = this.tabNames.indexOf(tabParam);
+        if (index !== -1) {
+          this.selectedTabIndex = index;
+        } else {
+          this.selectedTabIndex = 0;
+        }
+      } else {
+        this.updateQueryParams(this.selectedTabIndex);
+      }
+    });
+  }
+
+  onTabChange(event: MatTabChangeEvent): void {
+    this.selectedTabIndex = event.index;
+    this.updateQueryParams(event.index);
+  }
+
+  private updateQueryParams(tabIndex: number): void {
+    const tabName = this.tabNames[tabIndex];
+    if (tabName) {
+      this._router.navigate([], {
+        relativeTo: this._route,
+        queryParams: {subTab: tabName},
+        queryParamsHandling: 'merge'
+      });
+    }
+  }
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.html	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.html	(working copy)
@@ -0,0 +1 @@
+<p>resource-monitoring-asf works!</p>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.scss	(added)
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.scss	(revision 0)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.scss	(revision 0)
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.spec.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.spec.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.spec.ts	(working copy)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ResourceMonitoringAsf } from './resource-monitoring-asf';
+
+describe('ResourceMonitoringAsf', () => {
+  let component: ResourceMonitoringAsf;
+  let fixture: ComponentFixture<ResourceMonitoringAsf>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ResourceMonitoringAsf]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(ResourceMonitoringAsf);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-asf/resource-monitoring-asf.ts	(working copy)
@@ -0,0 +1,11 @@
+import { Component } from '@angular/core';
+
+@Component({
+  selector: 'app-resource-monitoring-asf',
+  imports: [],
+  templateUrl: './resource-monitoring-asf.html',
+  styleUrl: './resource-monitoring-asf.scss'
+})
+export class ResourceMonitoringAsf {
+
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.html	(working copy)
@@ -1 +1,89 @@
-<p>resource-monitoring-devices works!</p>
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-content>
+    <div class="table-container">
+      <div class="mat-elevation-z0">
+        <table mat-table [dataSource]="dataSource">
+          <ng-container matColumnDef="serial">
+            <th mat-header-cell *matHeaderCellDef>ID</th>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+          </ng-container>
+          <ng-container matColumnDef="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Device Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="details-page-link" (click)="goToDetails(element)">{{ element?.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceGroup">
+            <th mat-header-cell *matHeaderCellDef>Device Group</th>
+            <td mat-cell *matCellDef="let element">{{ element?.device_group }}</td>
+          </ng-container>
+          <ng-container matColumnDef="type">
+            <th mat-header-cell *matHeaderCellDef>Device Type</th>
+            <td mat-cell *matCellDef="let element">{{ element?.type }}</td>
+          </ng-container>
+          <ng-container matColumnDef="ip">
+            <th mat-header-cell *matHeaderCellDef>IP Address</th>
+            <td mat-cell *matCellDef="let element">{{ element?.ip }}</td>
+          </ng-container>
+          <ng-container matColumnDef="status">
+            <th mat-header-cell *matHeaderCellDef>Monitor Status</th>
+            <td mat-cell *matCellDef="let element">
+              @if (element?.snmp_general?.snmp_enable) {
+                <span class="success-icon">
+                  <fa-icon [icon]="['far', 'check-circle']" matTooltip="SNMP Enabled"></fa-icon>
+                </span>
+              } @else {
+                <span class="blue-icon">
+                  <fa-icon [icon]="['far', 'xmark-circle']" matTooltip="SNMP Disabled"></fa-icon>
+                </span>
+              }
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="stats">
+            <th mat-header-cell *matHeaderCellDef>Statistics</th>
+            <td mat-cell *matCellDef="let element">
+              <div class="stats-container">
+                <div class="stat-item">
+                  <span>CPU:</span>
+                  <div echarts [options]="getMiniBarOptions(30)" class="mini-chart" matTooltip="CPU"></div>
+                  <span class="progress-number">30 %</span>
+                </div>
+
+                <div class="stat-item">
+                  <span>System:</span>
+                  <div echarts [options]="getMiniBarOptions(60)" class="mini-chart" matTooltip="System Memory"></div>
+                  <span class="progress-number">60 %</span>
+                </div>
+
+                <div class="stat-item">
+                  <span>Network:</span>
+                  <div echarts [options]="getMiniBarOptions(90)" class="mini-chart" matTooltip="Network Memory"></div>
+                  <span class="progress-number">90 %</span>
+                </div>
+              </div>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="action">
+            <th mat-header-cell *matHeaderCellDef>Action</th>
+            <td mat-cell *matCellDef="let element">
+              <div class="row-action a-link">
+                <fa-icon [icon]="['fas', 'circle-info']" matTooltip="Show Info" class="fa-1x blue-icon" (click)="showDeviceInfo(element)"></fa-icon>
+              </div>
+            </td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="dataColumns"></tr>
+          <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="11">No results found.</td>
+          </tr>
+        </table>
+        <mat-paginator
+          [length]="totalRecords"
+          [pageSize]="10"
+          [pageSizeOptions]="[10, 20, 50]"
+        >
+        </mat-paginator>
+      </div>
+    </div>
+  </mat-card-content>
+</mat-card>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.scss	(working copy)
@@ -0,0 +1,47 @@
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
+
+.stats-container {
+  display: flex;
+  flex-direction: column;
+  gap: 4px;
+}
+
+.stat-item {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+}
+
+.mini-chart {
+  width: 80px;
+  height: 14px;
+  line-height: 0;
+  display: flex;
+  align-items: center;
+}
+
+.progress-number {
+  font-size: 12px;
+  min-width: 30px;
+  text-align: right;
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/resource-monitoring-devices.ts	(working copy)
@@ -1,11 +1,157 @@
-import { Component } from '@angular/core';
+import {Component, inject, OnInit, ViewChild} from '@angular/core';
+import {SharedModule} from '../../../shared/shared-module';
+import {take} from 'rxjs/operators';
+import {MatTableDataSource} from '@angular/material/table';
+import {DeviceService} from '../../../services/device-service';
+import {NotificationService} from '../../../services/notification';
+import {MatPaginator} from '@angular/material/paginator';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
+import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog';
+import {UtilsService} from '../../../services/utils-service';
 
 @Component({
   selector: 'app-resource-monitoring-devices',
-  imports: [],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './resource-monitoring-devices.html',
   styleUrl: './resource-monitoring-devices.scss'
 })
-export class ResourceMonitoringDevices {
+export class ResourceMonitoringDevices implements OnInit {
 
+  devices: any = [];
+  groups: any = [];
+  totalRecords: number = 0;
+  dataSource: MatTableDataSource<any> = new MatTableDataSource();
+  dataColumns: string[] = ['serial', 'deviceName', 'deviceGroup', 'type', 'ip', 'status', 'stats', 'action'];
+  @ViewChild(MatPaginator) paginator!: MatPaginator;
+
+  constructor(
+    private _device: DeviceService,
+    private _notification: NotificationService,
+  ) {
+  }
+
+  ngOnInit() {
+    setTimeout(() => {
+      this.getDeviceGroups();
+    })
+  }
+
+  getDeviceGroups(): void {
+    this.devices = [];
+    this.groups = [];
+    // ToDo: Update with actual RoleId
+    let roleId = "0"
+    let rawPayload = new FormData();
+    rawPayload.set('action', 'FilterRoleDeviceGroups');
+    rawPayload.set('options', JSON.stringify({"role_id": roleId}));
+    this._device.getDeviceGroups(rawPayload)
+      .pipe(take(1))
+      .subscribe({
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            if (result[1] && 'result' in result[1]) {
+              let groups = result[1].result;
+              groups.forEach((group: any) => {
+                this.groups.push(group?.group_name);
+                group?.device_list.forEach((device: any) => {
+                  this.devices.push(device);
+                })
+              })
+              this.dataSource.data = this.devices;
+              this.dataSource.paginator = this.paginator;
+              this.totalRecords = this.dataSource.data.length;
+            }
+          }
+        }, error: (error: { message: string; }) => {
+          console.log(error);
+          this._notification.showError(error.message);
+        }
+      })
+  }
+
+  getMiniBarOptions(value: number) {
+    return {
+      grid: {left: 0, right: 0, top: 0, bottom: 0},
+
+      // Y-axis is now the category axis
+      yAxis: {
+        type: 'category',
+        show: false,
+        data: [''],
+        axisLine: {show: false}
+      },
+
+      // X-axis is now the value axis
+      xAxis: {
+        type: 'value',
+        show: false,
+        min: 0,
+        max: 100,
+        splitLine: {show: false}
+      },
+
+      series: [
+        {
+          type: 'bar',
+          data: [value],
+          barWidth: 10, // Set the fixed height of the bar in pixels
+          barGap: '-100%',
+          itemStyle: {
+            color: value > 80 ? '#e53935' : value > 50 ? '#fb8c00' : '#43a047'
+          }
+        }
+      ]
+    };
+  }
+
+
+  goToDetails(_device: any) {
+
+  }
+
+  dialog = inject(MatDialog);
+  dialogConfig = new MatDialogConfig();
+
+  showDeviceInfo(_device: any) {
+    this.dialogConfig.data = {
+      device: {
+        'Name': _device.name,
+        'Model': _device?.model,
+        'Build Version': _device?.build_version,
+        'System Boot Time': _device?.system_boot_time,
+        'Serial Number': _device.serial_number,
+        'LicenseKey': _device?.license_key,
+        'Expiration Date': _device?.license_date,
+        'Connections Per Second': 0,
+        'Throughput - Received': '',
+        'Throughput - Sent': '',
+      }
+    }
+    const dialogRef = this.dialog.open(ShowDeviceInfoDialog, this.dialogConfig);
+    dialogRef.afterClosed().subscribe(isAdded => {
+    })
+  }
 }
+
+@Component({
+  selector: 'show-device-info',
+  templateUrl: './show-device-info.html',
+  imports: [SharedModule],
+})
+export class ShowDeviceInfoDialog implements OnInit {
+  readonly dialogRef = inject(MatDialogRef<ShowDeviceInfoDialog>);
+  readonly data = inject(MAT_DIALOG_DATA);
+  dataColumns: Array<string> = ['key', 'value'];
+  dataSource = new MatTableDataSource([]);
+
+  constructor(private _utils: UtilsService) {
+  }
+
+  ngOnInit() {
+    this.dataSource = this._utils.processConfigData(this.data?.device);
+  }
+
+  onCancel(): void {
+    this.dialogRef.close(false);
+  }
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/show-device-info.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/show-device-info.html	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-devices/show-device-info.html	(working copy)
@@ -0,0 +1,22 @@
+<h2 mat-dialog-title>Device Info - {{data?.device?.Name}}</h2>
+
+<mat-dialog-content>
+  <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
+    <ng-container matColumnDef="key">
+      <td mat-cell *matCellDef="let element"> {{ element.key }}</td>
+    </ng-container>
+    <ng-container matColumnDef="value">
+      <td mat-cell *matCellDef="let element"> {{ element.value }}</td>
+    </ng-container>
+    <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+  </table>
+</mat-dialog-content>
+
+<mat-dialog-actions align="center">
+  <button
+    mat-button
+    color="basic"
+    (click)="onCancel()">
+    Close
+  </button>
+</mat-dialog-actions>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.html	(working copy)
@@ -1 +1,73 @@
-<p>resource-monitoring-llb works!</p>
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-content>
+    <div class="table-container">
+      <div class="mat-elevation-z0">
+        <table mat-table [dataSource]="dataSource">
+          <ng-container matColumnDef="serial">
+            <th mat-header-cell *matHeaderCellDef>ID</th>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+          </ng-container>
+          <ng-container matColumnDef="serviceName">
+            <th mat-header-cell *matHeaderCellDef>Service Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="details-page-link" (click)="goToDetails(element)">{{ element?.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="gatewayIp">
+            <th mat-header-cell *matHeaderCellDef>Gateway IP</th>
+            <td mat-cell *matCellDef="let element">{{ element?.device_group }}</td>
+          </ng-container>
+          <ng-container matColumnDef="deviceIp">
+            <th mat-header-cell *matHeaderCellDef>Device IP</th>
+            <td mat-cell *matCellDef="let element">{{ element }}</td>
+          </ng-container>
+          <ng-container matColumnDef="healthStatus">
+            <th mat-header-cell *matHeaderCellDef>Health Status</th>
+            <td mat-cell *matCellDef="let element">
+              @if (element?.snmp_general?.snmp_enable) {
+                <span class="success-icon">
+                  <fa-icon [icon]="['far', 'check-circle']" matTooltip="SNMP Enabled"></fa-icon>
+                </span>
+              } @else {
+                <span class="blue-icon">
+                  <fa-icon [icon]="['far', 'xmark-circle']" matTooltip="SNMP Disabled"></fa-icon>
+                </span>
+              }
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Device Name</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="deviceGroup">
+            <th mat-header-cell *matHeaderCellDef>Device Group</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="bandwidth">
+            <th mat-header-cell *matHeaderCellDef>Bandwidth Usage</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="connections">
+            <th mat-header-cell *matHeaderCellDef>Connections</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="throughput">
+            <th mat-header-cell *matHeaderCellDef>Throughput</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="dataColumns"></tr>
+          <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="11">No results found.</td>
+          </tr>
+        </table>
+        <mat-paginator
+          [length]="totalRecords"
+          [pageSize]="10"
+          [pageSizeOptions]="[10, 20, 50]"
+        >
+        </mat-paginator>
+      </div>
+    </div>
+  </mat-card-content>
+</mat-card>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.scss	(working copy)
@@ -0,0 +1,21 @@
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-llb/resource-monitoring-llb.ts	(working copy)
@@ -1,11 +1,69 @@
-import { Component } from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {SharedModule} from '../../../shared/shared-module';
+import {MatTableDataSource} from '@angular/material/table';
+import {MatPaginator} from '@angular/material/paginator';
+import {DeviceService} from '../../../services/device-service';
+import {NotificationService} from '../../../services/notification';
+import {take} from 'rxjs/operators';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-resource-monitoring-llb',
-  imports: [],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './resource-monitoring-llb.html',
   styleUrl: './resource-monitoring-llb.scss'
 })
-export class ResourceMonitoringLlb {
+export class ResourceMonitoringLlb implements OnInit {
 
+  devices: any = [];
+  groups: any = [];
+  totalRecords: number = 0;
+  dataSource: MatTableDataSource<any> = new MatTableDataSource();
+  dataColumns: string[] = ['serial', 'serviceName', 'gatewayIp', 'deviceIp', 'healthStatus', 'deviceName', 'bandwidth', 'connections', 'throughput'];
+  @ViewChild(MatPaginator) paginator!: MatPaginator;
+
+  constructor(
+    private _device: DeviceService,
+    private _notification: NotificationService,
+  ) {
+  }
+
+  ngOnInit() {
+    setTimeout(() => {
+      this.getDeviceGroups();
+    })
+  }
+
+  getDeviceGroups(): void {
+    this.devices = [];
+    this.groups = [];
+    // ToDo: Update with actual RoleId
+    let roleId = "0"
+    let rawPayload = new FormData();
+    rawPayload.set('action', 'FilterRoleDeviceGroups');
+    rawPayload.set('options', JSON.stringify({"role_id": roleId}));
+    this._device.getDeviceGroups(rawPayload)
+      .pipe(take(1))
+      .subscribe({
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            if (result[1] && 'result' in result[1]) {
+              let groups = result[1].result;
+              groups.forEach((group: any) => {
+                this.groups.push(group?.group_name);
+                group?.device_list.forEach((device: any) => {
+                  this.devices.push(device);
+                })
+              })
+            }
+          }
+        }, error: (error: { message: string; }) => {
+          console.log(error);
+          this._notification.showError(error.message);
+        }
+      })
+  }
+
+  goToDetails(_service: any) {
+  }
 }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.html	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.html	(working copy)
@@ -0,0 +1,69 @@
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-content>
+    <div class="table-container">
+      <div class="mat-elevation-z0">
+        <table mat-table [dataSource]="dataSource">
+          <ng-container matColumnDef="serial">
+            <th mat-header-cell *matHeaderCellDef>ID</th>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+          </ng-container>
+          <ng-container matColumnDef="serviceName">
+            <th mat-header-cell *matHeaderCellDef>Service Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="details-page-link" (click)="goToDetails(element)">{{ element?.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="serviceType">
+            <th mat-header-cell *matHeaderCellDef>Service Type</th>
+            <td mat-cell *matCellDef="let element">{{ element?.device_group }}</td>
+          </ng-container>
+          <ng-container matColumnDef="ip">
+            <th mat-header-cell *matHeaderCellDef>IP Address & Port</th>
+            <td mat-cell *matCellDef="let element">{{ element }}</td>
+          </ng-container>
+          <ng-container matColumnDef="healthStatus">
+            <th mat-header-cell *matHeaderCellDef>Health Status</th>
+            <td mat-cell *matCellDef="let element">
+              @if (element?.snmp_general?.snmp_enable) {
+                <span class="success-icon">
+                  <fa-icon [icon]="['far', 'check-circle']" matTooltip="SNMP Enabled"></fa-icon>
+                </span>
+              } @else {
+                <span class="blue-icon">
+                  <fa-icon [icon]="['far', 'xmark-circle']" matTooltip="SNMP Disabled"></fa-icon>
+                </span>
+              }
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Device Name</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="deviceGroup">
+            <th mat-header-cell *matHeaderCellDef>Device Group</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="connections">
+            <th mat-header-cell *matHeaderCellDef>Connections</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="throughput">
+            <th mat-header-cell *matHeaderCellDef>Throughput</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="dataColumns"></tr>
+          <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="11">No results found.</td>
+          </tr>
+        </table>
+        <mat-paginator
+          [length]="totalRecords"
+          [pageSize]="10"
+          [pageSizeOptions]="[10, 20, 50]"
+        >
+        </mat-paginator>
+      </div>
+    </div>
+  </mat-card-content>
+</mat-card>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.scss	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.scss	(working copy)
@@ -0,0 +1,21 @@
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.spec.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.spec.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.spec.ts	(working copy)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ResourceMonitoringSlbReal } from './resource-monitoring-slb-real';
+
+describe('ResourceMonitoringSlbReal', () => {
+  let component: ResourceMonitoringSlbReal;
+  let fixture: ComponentFixture<ResourceMonitoringSlbReal>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ResourceMonitoringSlbReal]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(ResourceMonitoringSlbReal);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-real/resource-monitoring-slb-real.ts	(working copy)
@@ -0,0 +1,69 @@
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {SharedModule} from '../../../shared/shared-module';
+import {MatTableDataSource} from '@angular/material/table';
+import {MatPaginator} from '@angular/material/paginator';
+import {DeviceService} from '../../../services/device-service';
+import {NotificationService} from '../../../services/notification';
+import {take} from 'rxjs/operators';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
+
+@Component({
+  selector: 'app-resource-monitoring-slb-real',
+  imports: [SharedModule, GlobalSerialPipe],
+  templateUrl: './resource-monitoring-slb-real.html',
+  styleUrl: './resource-monitoring-slb-real.scss'
+})
+export class ResourceMonitoringSlbReal implements OnInit {
+
+  devices: any = [];
+  groups: any = [];
+  totalRecords: number = 0;
+  dataSource: MatTableDataSource<any> = new MatTableDataSource();
+  dataColumns: string[] = ['serial', 'serviceName', 'serviceType', 'ip', 'healthStatus', 'deviceName', 'deviceGroup', 'connections', 'throughput'];
+  @ViewChild(MatPaginator) paginator!: MatPaginator;
+
+  constructor(
+    private _device: DeviceService,
+    private _notification: NotificationService,
+  ) {
+  }
+
+  ngOnInit() {
+    setTimeout(() => {
+      this.getDeviceGroups();
+    })
+  }
+
+  getDeviceGroups(): void {
+    this.devices = [];
+    this.groups = [];
+    // ToDo: Update with actual RoleId
+    let roleId = "0"
+    let rawPayload = new FormData();
+    rawPayload.set('action', 'FilterRoleDeviceGroups');
+    rawPayload.set('options', JSON.stringify({"role_id": roleId}));
+    this._device.getDeviceGroups(rawPayload)
+      .pipe(take(1))
+      .subscribe({
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            if (result[1] && 'result' in result[1]) {
+              let groups = result[1].result;
+              groups.forEach((group: any) => {
+                this.groups.push(group?.group_name);
+                group?.device_list.forEach((device: any) => {
+                  this.devices.push(device);
+                })
+              })
+            }
+          }
+        }, error: (error: { message: string; }) => {
+          console.log(error);
+          this._notification.showError(error.message);
+        }
+      })
+  }
+
+  goToDetails(_service: any) {
+  }
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.html	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.html	(working copy)
@@ -0,0 +1,73 @@
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-content>
+    <div class="table-container">
+      <div class="mat-elevation-z0">
+        <table mat-table [dataSource]="dataSource">
+          <ng-container matColumnDef="serial">
+            <th mat-header-cell *matHeaderCellDef>ID</th>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+          </ng-container>
+          <ng-container matColumnDef="serviceName">
+            <th mat-header-cell *matHeaderCellDef>Service Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="details-page-link" (click)="goToDetails(element)">{{ element?.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="serviceType">
+            <th mat-header-cell *matHeaderCellDef>Service Type</th>
+            <td mat-cell *matCellDef="let element">{{ element?.device_group }}</td>
+          </ng-container>
+          <ng-container matColumnDef="ip">
+            <th mat-header-cell *matHeaderCellDef>IP Address & Port</th>
+            <td mat-cell *matCellDef="let element">{{ element }}</td>
+          </ng-container>
+          <ng-container matColumnDef="healthStatus">
+            <th mat-header-cell *matHeaderCellDef>Health Status</th>
+            <td mat-cell *matCellDef="let element">
+              @if (element?.snmp_general?.snmp_enable) {
+                <span class="success-icon">
+                  <fa-icon [icon]="['far', 'check-circle']" matTooltip="SNMP Enabled"></fa-icon>
+                </span>
+              } @else {
+                <span class="blue-icon">
+                  <fa-icon [icon]="['far', 'xmark-circle']" matTooltip="SNMP Disabled"></fa-icon>
+                </span>
+              }
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Device Name</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="deviceGroup">
+            <th mat-header-cell *matHeaderCellDef>Device Group</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="connections">
+            <th mat-header-cell *matHeaderCellDef>Connections</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="throughput">
+            <th mat-header-cell *matHeaderCellDef>Throughput</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="certificate">
+            <th mat-header-cell *matHeaderCellDef>Certificate</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="dataColumns"></tr>
+          <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="11">No results found.</td>
+          </tr>
+        </table>
+        <mat-paginator
+          [length]="totalRecords"
+          [pageSize]="10"
+          [pageSizeOptions]="[10, 20, 50]"
+        >
+        </mat-paginator>
+      </div>
+    </div>
+  </mat-card-content>
+</mat-card>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.scss	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.scss	(working copy)
@@ -0,0 +1,21 @@
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.spec.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.spec.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.spec.ts	(working copy)
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { ResourceMonitoringSlbVirtual } from './resource-monitoring-slb-virtual';
+
+describe('ResourceMonitoringSlbVirtual', () => {
+  let component: ResourceMonitoringSlbVirtual;
+  let fixture: ComponentFixture<ResourceMonitoringSlbVirtual>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      imports: [ResourceMonitoringSlbVirtual]
+    })
+    .compileComponents();
+
+    fixture = TestBed.createComponent(ResourceMonitoringSlbVirtual);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-slb-virtual/resource-monitoring-slb-virtual.ts	(working copy)
@@ -0,0 +1,70 @@
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {SharedModule} from '../../../shared/shared-module';
+import {MatTableDataSource} from '@angular/material/table';
+import {MatPaginator} from '@angular/material/paginator';
+import {DeviceService} from '../../../services/device-service';
+import {NotificationService} from '../../../services/notification';
+import {take} from 'rxjs/operators';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
+
+@Component({
+  selector: 'app-resource-monitoring-slb-virtual',
+  imports: [SharedModule, GlobalSerialPipe],
+  templateUrl: './resource-monitoring-slb-virtual.html',
+  styleUrl: './resource-monitoring-slb-virtual.scss'
+})
+export class ResourceMonitoringSlbVirtual implements OnInit {
+
+  devices: any = [];
+  groups: any = [];
+  totalRecords: number = 0;
+  dataSource: MatTableDataSource<any> = new MatTableDataSource();
+  dataColumns: string[] = ['serial', 'serviceName', 'serviceType', 'ip', 'healthStatus', 'deviceName', 'deviceGroup', 'connections', 'throughput', 'certificate'];
+  @ViewChild(MatPaginator) paginator!: MatPaginator;
+
+  constructor(
+    private _device: DeviceService,
+    private _notification: NotificationService,
+  ) {
+  }
+
+  ngOnInit() {
+    setTimeout(() => {
+      this.getDeviceGroups();
+    })
+  }
+
+  getDeviceGroups(): void {
+    this.devices = [];
+    this.groups = [];
+    // ToDo: Update with actual RoleId
+    let roleId = "0"
+    let rawPayload = new FormData();
+    rawPayload.set('action', 'FilterRoleDeviceGroups');
+    rawPayload.set('options', JSON.stringify({"role_id": roleId}));
+    this._device.getDeviceGroups(rawPayload)
+      .pipe(take(1))
+      .subscribe({
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            if (result[1] && 'result' in result[1]) {
+              let groups = result[1].result;
+              groups.forEach((group: any) => {
+                this.groups.push(group?.group_name);
+                group?.device_list.forEach((device: any) => {
+                  this.devices.push(device);
+                })
+              })
+            }
+          }
+        }, error: (error: { message: string; }) => {
+          console.log(error);
+          this._notification.showError(error.message);
+        }
+      })
+  }
+
+  goToDetails(_service: any) {
+  }
+
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.html	(working copy)
@@ -1 +1,51 @@
-<p>resource-monitoring-ssl-vpn works!</p>
+<mat-card class="page-card-1" appearance="filled">
+  <mat-card-content>
+    <div class="table-container">
+      <div class="mat-elevation-z0">
+        <table mat-table [dataSource]="dataSource">
+          <ng-container matColumnDef="serial">
+            <th mat-header-cell *matHeaderCellDef>ID</th>
+            <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+          </ng-container>
+          <ng-container matColumnDef="serviceName">
+            <th mat-header-cell *matHeaderCellDef>Service Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="details-page-link" (click)="goToDetails(element)">{{ element?.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="ipList">
+            <th mat-header-cell *matHeaderCellDef>IP List</th>
+            <td mat-cell *matCellDef="let element">{{ element?.device_group }}</td>
+          </ng-container>
+          <ng-container matColumnDef="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Device Name</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="deviceGroup">
+            <th mat-header-cell *matHeaderCellDef>Device Group</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="sessions">
+            <th mat-header-cell *matHeaderCellDef>Sessions</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <ng-container matColumnDef="certificate">
+            <th mat-header-cell *matHeaderCellDef>Certificate</th>
+            <td mat-cell *matCellDef="let element"></td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="dataColumns"></tr>
+          <tr mat-row *matRowDef="let row; columns: dataColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="11">No results found.</td>
+          </tr>
+        </table>
+        <mat-paginator
+          [length]="totalRecords"
+          [pageSize]="10"
+          [pageSizeOptions]="[10, 20, 50]"
+        >
+        </mat-paginator>
+      </div>
+    </div>
+  </mat-card-content>
+</mat-card>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.scss	(working copy)
@@ -0,0 +1,21 @@
+.page-card-1 {
+  width: 100%;
+  border-radius: 0;
+  background-color: inherit;
+  font-size: 14px !important;
+
+  mat-card-header {
+    color: #1170cf;
+  }
+}
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/resource-monitoring-ssl-vpn/resource-monitoring-ssl-vpn.ts	(working copy)
@@ -1,11 +1,69 @@
-import { Component } from '@angular/core';
+import {Component, OnInit, ViewChild} from '@angular/core';
+import {SharedModule} from '../../../shared/shared-module';
+import {MatTableDataSource} from '@angular/material/table';
+import {MatPaginator} from '@angular/material/paginator';
+import {DeviceService} from '../../../services/device-service';
+import {NotificationService} from '../../../services/notification';
+import {take} from 'rxjs/operators';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-resource-monitoring-ssl-vpn',
-  imports: [],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './resource-monitoring-ssl-vpn.html',
   styleUrl: './resource-monitoring-ssl-vpn.scss'
 })
-export class ResourceMonitoringSslVpn {
+export class ResourceMonitoringSslVpn implements OnInit {
 
+  devices: any = [];
+  groups: any = [];
+  totalRecords: number = 0;
+  dataSource: MatTableDataSource<any> = new MatTableDataSource();
+  dataColumns: string[] = ['serial', 'serviceName', 'ipList', 'deviceName', 'deviceGroup', 'sessions', 'certificate'];
+  @ViewChild(MatPaginator) paginator!: MatPaginator;
+
+  constructor(
+    private _device: DeviceService,
+    private _notification: NotificationService,
+  ) {
+  }
+
+  ngOnInit() {
+    setTimeout(() => {
+      this.getDeviceGroups();
+    })
+  }
+
+  getDeviceGroups(): void {
+    this.devices = [];
+    this.groups = [];
+    // ToDo: Update with actual RoleId
+    let roleId = "0"
+    let rawPayload = new FormData();
+    rawPayload.set('action', 'FilterRoleDeviceGroups');
+    rawPayload.set('options', JSON.stringify({"role_id": roleId}));
+    this._device.getDeviceGroups(rawPayload)
+      .pipe(take(1))
+      .subscribe({
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            if (result[1] && 'result' in result[1]) {
+              let groups = result[1].result;
+              groups.forEach((group: any) => {
+                this.groups.push(group?.group_name);
+                group?.device_list.forEach((device: any) => {
+                  this.devices.push(device);
+                })
+              })
+            }
+          }
+        }, error: (error: { message: string; }) => {
+          console.log(error);
+          this._notification.showError(error.message);
+        }
+      })
+  }
+
+  goToDetails(_service: any) {
+  }
 }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-details/role-details.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-details/role-details.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-details/role-details.html	(working copy)
@@ -17,7 +17,7 @@
   <table mat-table [dataSource]="deviceGroupDataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef>Id.</th>
-      <td mat-cell *matCellDef="let element; let i = index;">{{ i + 1 }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;">{{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="groups">
       <th mat-header-cell *matHeaderCellDef>Device Group</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-details/role-details.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-details/role-details.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-details/role-details.ts	(working copy)
@@ -7,10 +7,11 @@
 import {Confirmation} from '../../../services/confirmation';
 import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-role-details',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './role-details.html',
   styleUrl: './role-details.scss'
 })
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-management/role-management.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-management/role-management.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-management/role-management.html	(working copy)
@@ -7,7 +7,7 @@
   <table mat-table [dataSource]="roleDataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef>Id.</th>
-      <td mat-cell *matCellDef="let element; let i = index;">{{ i + 1 }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;">{{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="role_name">
       <th mat-header-cell *matHeaderCellDef>Role Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-management/role-management.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-management/role-management.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/role-management/role-management.ts	(working copy)
@@ -9,10 +9,11 @@
 import {Router} from '@angular/router';
 import {MatPaginator} from '@angular/material/paginator';
 import {MatTableDataSource} from '@angular/material/table';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-role-management',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './role-management.html',
   styleUrl: './role-management.scss'
 })
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.html	(working copy)
@@ -10,7 +10,7 @@
       <table mat-table [dataSource]="backupDatasource" class="mat-elevation-z1">
         <ng-container matColumnDef="serial">
           <th mat-header-cell *matHeaderCellDef> No.</th>
-          <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+          <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
         </ng-container>
         <ng-container matColumnDef="location">
           <th mat-header-cell *matHeaderCellDef> Backup Location</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.scss	(working copy)
@@ -3,7 +3,20 @@
   border-radius: 0;
   background-color: inherit;
   font-size: 14px !important;
+
   mat-card-header {
     color: #1170cf;
   }
 }
+
+mat-card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 4px 10px;
+}
+
+mat-card-title {
+  font-size: medium;
+}
+
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-backup-restore/system-backup-restore.ts	(working copy)
@@ -21,11 +21,13 @@
 import {catchError, Subject, throwError} from 'rxjs';
 import {HttpClient, HttpErrorResponse} from '@angular/common/http';
 import {saveAs} from 'file-saver';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-system-backup-restore',
   imports: [
     SharedModule,
+    GlobalSerialPipe,
   ],
   templateUrl: './system-backup-restore.html',
   styleUrl: './system-backup-restore.scss'
@@ -90,13 +92,6 @@
       })
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   getScheduledBackupFiles(): void {
     this.scheduledBackupDatasource = new MatTableDataSource();
     this.systemService.getScheduledBackupFiles()
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-time/system-time.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-time/system-time.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-time/system-time.html	(working copy)
@@ -1,180 +1,191 @@
-<mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <mat-card-title>System Date & Time</mat-card-title>
-  </mat-card-header>
-  <mat-card-content>
-    <form
-      (ngSubmit)="updateSystemDateTime()"
-      [formGroup]="dateTimeForm"
-      class="system-datetime-form"
-    >
-      <div class="form-field-wrapper">
-        <label for="systemDate" class="form-label">System Date *</label>
-        <mat-form-field appearance="outline" subscriptSizing="dynamic">
-          <input
-            id="systemDate"
-            formControlName="systemDate"
-            matInput
-            placeholder="System Date"
-            [matDatepicker]="datePicker"
-          />
-          <mat-datepicker-toggle matIconSuffix [for]="datePicker"/>
-          <mat-datepicker #datePicker/>
-          <mat-hint>MM/DD/YYYY</mat-hint>
-          @if (dateTimeForm.get('systemDate')?.invalid && dateTimeForm.get('systemDate')?.touched) {
-            <mat-error>
-              @if (dateTimeForm.get('systemDate')?.errors?.['required']) {
-                Date is required.
-              } @else {
-                Invalid date format (Expected: MM/DD/YYYY).
-              }
-            </mat-error>
-          }
-        </mat-form-field>
-      </div>
-      <div class="form-field-wrapper">
-        <label for="systemTime" class="form-label">System Time *</label>
-        <mat-form-field appearance="outline" subscriptSizing="dynamic">
-          <input
-            id="systemTime"
-            formControlName="systemTime"
-            matInput
-            placeholder="System Time"
-            [matTimepicker]="timePicker"
-            matTimepickerMin="00:00"
-            matTimepickerMax="23:59"
-          />
-          <mat-timepicker-toggle matIconSuffix [for]="timePicker"/>
-          <mat-timepicker #timePicker/>
-          <mat-hint>12:00 PM</mat-hint>
-          @if (dateTimeForm.get('systemTime')?.invalid && dateTimeForm.get('systemTime')?.touched) {
-            <mat-error>
-              @if (dateTimeForm.get('systemTime')?.errors?.['required']) {
-                Time is required.
-              } @else {
-                Invalid time format (Expected: HH:MM AM/PM).
-              }
-            </mat-error>
-          }
-        </mat-form-field>
-      </div>
-      <div class="form-field-wrapper">
-        <label for="systemTimezone" class="form-label">System Timezone *</label>
-        <mat-form-field appearance="outline" subscriptSizing="dynamic">
-          <mat-label>Continent/Main Zone</mat-label>
-          <mat-select formControlName="selectedParent" id="systemTimezone">
-            @for (parent of parentTimezones; track parent.name) {
-              <mat-option [value]="parent.name"> {{ parent.name }}</mat-option>
-            }
-          </mat-select>
-          <!--          <mat-error *ngIf="hasError('selectedParent', 'required')">Please select a parent zone</mat-error>-->
-        </mat-form-field>
-        <!--      </div>-->
-        @if (childTimezones.length > 0) {
-          <!--        <div class="form-field-wrapper">-->
-            <!--          <label class="form-label"></label>-->
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <mat-label>Country/Region</mat-label>
-            <mat-select formControlName="selectedChild">
-              @for (child of childTimezones; track child.name) {
-                <mat-option [value]="child.name"> {{ child.name }}</mat-option>
-              }
-            </mat-select>
-            <!--          <mat-error *ngIf="hasError('selectedChild', 'required')">Please select a country/region</mat-error>-->
-          </mat-form-field>
-          <!--        </div>-->
-        }
+<div class="tab-container">
+  <mat-tab-group mat-stretch-tabs="false" animationDuration="0ms">
+    <mat-tab label="System Date & Time">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <mat-card class="page-card-1" appearance="filled">
+            <mat-card-content>
+              <form
+                (ngSubmit)="updateSystemDateTime()"
+                [formGroup]="dateTimeForm"
+                class="system-datetime-form"
+              >
+                <div class="form-field-wrapper">
+                  <label for="systemDate" class="form-label">System Date *</label>
+                  <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                    <input
+                      id="systemDate"
+                      formControlName="systemDate"
+                      matInput
+                      placeholder="System Date"
+                      [matDatepicker]="datePicker"
+                    />
+                    <mat-datepicker-toggle matIconSuffix [for]="datePicker"/>
+                    <mat-datepicker #datePicker/>
+                    <mat-hint>MM/DD/YYYY</mat-hint>
+                    @if (dateTimeForm.get('systemDate')?.invalid && dateTimeForm.get('systemDate')?.touched) {
+                      <mat-error>
+                        @if (dateTimeForm.get('systemDate')?.errors?.['required']) {
+                          Date is required.
+                        } @else {
+                          Invalid date format (Expected: MM/DD/YYYY).
+                        }
+                      </mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-field-wrapper">
+                  <label for="systemTime" class="form-label">System Time *</label>
+                  <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                    <input
+                      id="systemTime"
+                      formControlName="systemTime"
+                      matInput
+                      placeholder="System Time"
+                      [matTimepicker]="timePicker"
+                      matTimepickerMin="00:00"
+                      matTimepickerMax="23:59"
+                    />
+                    <mat-timepicker-toggle matIconSuffix [for]="timePicker"/>
+                    <mat-timepicker #timePicker/>
+                    <mat-hint>12:00 PM</mat-hint>
+                    @if (dateTimeForm.get('systemTime')?.invalid && dateTimeForm.get('systemTime')?.touched) {
+                      <mat-error>
+                        @if (dateTimeForm.get('systemTime')?.errors?.['required']) {
+                          Time is required.
+                        } @else {
+                          Invalid time format (Expected: HH:MM AM/PM).
+                        }
+                      </mat-error>
+                    }
+                  </mat-form-field>
+                </div>
+                <div class="form-field-wrapper">
+                  <label for="systemTimezone" class="form-label">System Timezone *</label>
+                  <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                    <mat-label>Continent/Main Zone</mat-label>
+                    <mat-select formControlName="selectedParent" id="systemTimezone">
+                      @for (parent of parentTimezones; track parent.name) {
+                        <mat-option [value]="parent.name"> {{ parent.name }}</mat-option>
+                      }
+                    </mat-select>
+                    <!--          <mat-error *ngIf="hasError('selectedParent', 'required')">Please select a parent zone</mat-error>-->
+                  </mat-form-field>
+                  <!--      </div>-->
+                  @if (childTimezones.length > 0) {
+                    <!--        <div class="form-field-wrapper">-->
+                      <!--          <label class="form-label"></label>-->
+                    <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                      <mat-label>Country/Region</mat-label>
+                      <mat-select formControlName="selectedChild">
+                        @for (child of childTimezones; track child.name) {
+                          <mat-option [value]="child.name"> {{ child.name }}</mat-option>
+                        }
+                      </mat-select>
+                      <!--          <mat-error *ngIf="hasError('selectedChild', 'required')">Please select a country/region</mat-error>-->
+                    </mat-form-field>
+                    <!--        </div>-->
+                  }
 
-        @if (grandchildTimezones.length > 0) {
-          <!--        <div class="form-field-wrapper">-->
-            <!--          <label class="form-label"></label>-->
-          <mat-form-field appearance="outline" subscriptSizing="dynamic">
-            <mat-label>City/Area</mat-label>
-            <mat-select formControlName="selectedGrandchild">
-              @for (grandchild of grandchildTimezones; track grandchild.name) {
-                <mat-option [value]="grandchild.name"> {{ grandchild.name }}</mat-option>
-              }
-            </mat-select>
-            <!--          <mat-error *ngIf="hasError('selectedGrandchild', 'required')">Please select a city/area</mat-error>-->
-          </mat-form-field>
-          <!--        </div>-->
-        }
-      </div>
-      <div class="submit-button-wrapper">
-        <button
-          type="submit"
-          mat-raised-button
-          color="primary">
-          Submit
-        </button>
-      </div>
-    </form>
-  </mat-card-content>
-</mat-card>
-<mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <mat-card-title>NTP</mat-card-title>
-  </mat-card-header>
-  <mat-card-content>
-    <div class="form-field-wrapper">
-      <mat-slide-toggle labelPosition="before" [(ngModel)]="isSystemNTPEnabled"
-                        (change)="onNTPToggleChange($event)">Enable NTP
-      </mat-slide-toggle>
-    </div>
-  </mat-card-content>
-</mat-card>
-<mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <mat-card-title>NTP Servers</mat-card-title>
-  </mat-card-header>
-  <mat-card-content>
-    <div class="button-container">
-      <button mat-raised-button (click)="addNTPServer()" [disabled]="isNTPEnabled"
-              matTooltip="Add NTP Server">Add
-      </button>
-    </div>
-    <div class="table-container">
-      <table mat-table [dataSource]="ntpDataSource" class="mat-elevation-z1">
-        <ng-container matColumnDef="serial">
-          <th mat-header-cell *matHeaderCellDef> No.</th>
-          <td mat-cell *matCellDef="let element; let i = index;"> {{ i + 1 }}</td>
-        </ng-container>
-        <ng-container matColumnDef="ip">
-          <th mat-header-cell *matHeaderCellDef> IP Address</th>
-          <td mat-cell *matCellDef="let element"> {{ element.ip }}</td>
-        </ng-container>
-        <ng-container matColumnDef="version">
-          <th mat-header-cell *matHeaderCellDef> NTP version</th>
-          <td mat-cell *matCellDef="let element"> {{ element.version }}</td>
-        </ng-container>
-        <ng-container matColumnDef="action">
-          <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
-          <td mat-cell *matCellDef="let element">
-            <div class="row-action a-link">
-              @if (!isNTPEnabled) {
-                <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete NTP Server"
-                         (click)="deleteNTPServer(element)"></fa-icon>
-              } @else {
-                <fa-icon [icon]="['far', 'trash-can']" size="lg" disabled
-                         matTooltip="Not allowed when NTP is enabled."></fa-icon>
-              }
-            </div>
-          </td>
-        </ng-container>
-        <tr mat-header-row *matHeaderRowDef="ntpColumns"></tr>
-        <tr mat-row *matRowDef="let row; columns: ntpColumns;"></tr>
-        <tr class="mat-row table-no-data" *matNoDataRow>
-          <td class="mat-cell" colspan="4">No results found.</td>
-        </tr>
-      </table>
-    </div>
-  </mat-card-content>
-</mat-card>
-<mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <mat-card-title>NTP Status</mat-card-title>
-  </mat-card-header>
-  <mat-card-content>
-    <pre class="wrapped-pre">{{ ntpStats }}</pre>
-  </mat-card-content>
-</mat-card>
+                  @if (grandchildTimezones.length > 0) {
+                    <!--        <div class="form-field-wrapper">-->
+                      <!--          <label class="form-label"></label>-->
+                    <mat-form-field appearance="outline" subscriptSizing="dynamic">
+                      <mat-label>City/Area</mat-label>
+                      <mat-select formControlName="selectedGrandchild">
+                        @for (grandchild of grandchildTimezones; track grandchild.name) {
+                          <mat-option [value]="grandchild.name"> {{ grandchild.name }}</mat-option>
+                        }
+                      </mat-select>
+                      <!--          <mat-error *ngIf="hasError('selectedGrandchild', 'required')">Please select a city/area</mat-error>-->
+                    </mat-form-field>
+                    <!--        </div>-->
+                  }
+                </div>
+                <div class="submit-button-wrapper">
+                  <button
+                    type="submit"
+                    mat-raised-button
+                    color="primary">
+                    Submit
+                  </button>
+                </div>
+              </form>
+            </mat-card-content>
+          </mat-card>
+        </div>
+      </ng-template>
+    </mat-tab>
+    <mat-tab label="NTP">
+      <ng-template matTabContent>
+        <div class="tab-content">
+          <mat-card class="page-card-1" appearance="filled">
+            <mat-card-content>
+              <div class="form-field-wrapper">
+                <mat-slide-toggle labelPosition="before" [(ngModel)]="isSystemNTPEnabled"
+                                  (change)="onNTPToggleChange($event)">Enable NTP
+                </mat-slide-toggle>
+              </div>
+            </mat-card-content>
+          </mat-card>
+          <mat-card class="page-card-1" appearance="filled">
+            <mat-card-header>
+              <mat-card-title>NTP Servers</mat-card-title>
+            </mat-card-header>
+            <mat-card-content>
+              <div class="button-container">
+                <button mat-raised-button (click)="addNTPServer()" [disabled]="isNTPEnabled"
+                        matTooltip="Add NTP Server">Add
+                </button>
+              </div>
+              <div class="table-container">
+                <table mat-table [dataSource]="ntpDataSource" class="mat-elevation-z1">
+                  <ng-container matColumnDef="serial">
+                    <th mat-header-cell *matHeaderCellDef> No.</th>
+                    <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
+                  </ng-container>
+                  <ng-container matColumnDef="ip">
+                    <th mat-header-cell *matHeaderCellDef> IP Address</th>
+                    <td mat-cell *matCellDef="let element"> {{ element.ip }}</td>
+                  </ng-container>
+                  <ng-container matColumnDef="version">
+                    <th mat-header-cell *matHeaderCellDef> NTP version</th>
+                    <td mat-cell *matCellDef="let element"> {{ element.version }}</td>
+                  </ng-container>
+                  <ng-container matColumnDef="action">
+                    <th mat-header-cell *matHeaderCellDef class="action-header w-10"> Action</th>
+                    <td mat-cell *matCellDef="let element">
+                      <div class="row-action a-link">
+                        @if (!isNTPEnabled) {
+                          <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon"
+                                   matTooltip="Delete NTP Server"
+                                   (click)="deleteNTPServer(element)"></fa-icon>
+                        } @else {
+                          <fa-icon [icon]="['far', 'trash-can']" size="lg" disabled
+                                   matTooltip="Not allowed when NTP is enabled."></fa-icon>
+                        }
+                      </div>
+                    </td>
+                  </ng-container>
+                  <tr mat-header-row *matHeaderRowDef="ntpColumns"></tr>
+                  <tr mat-row *matRowDef="let row; columns: ntpColumns;"></tr>
+                  <tr class="mat-row table-no-data" *matNoDataRow>
+                    <td class="mat-cell" colspan="4">No results found.</td>
+                  </tr>
+                </table>
+              </div>
+            </mat-card-content>
+          </mat-card>
+          <mat-card class="page-card-1" appearance="filled">
+            <mat-card-header>
+              <mat-card-title>NTP Status</mat-card-title>
+            </mat-card-header>
+            <mat-card-content>
+              <pre class="wrapped-pre">{{ ntpStats }}</pre>
+            </mat-card-content>
+          </mat-card>
+        </div>
+      </ng-template>
+    </mat-tab>
+  </mat-tab-group>
+</div>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-time/system-time.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-time/system-time.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/system-time/system-time.ts	(working copy)
@@ -9,19 +9,21 @@
 import {CustomValidators} from '../../../utils/custom-validators';
 import {Confirmation} from '../../../services/confirmation';
 import {AN_TZ} from '../../../constants/system-supported-timezones';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-system-time',
   imports: [
-    SharedModule
+    SharedModule,
+    GlobalSerialPipe,
   ],
   templateUrl: './system-time.html',
   styleUrl: './system-time.scss'
 })
 export class SystemTime implements OnInit {
 
-  isNTPEnabled: boolean = false; // readonly variable for system value
-  isSystemNTPEnabled: boolean = false; // form-field value.
+  isNTPEnabled: boolean = false;
+  isSystemNTPEnabled: boolean = false;
   ntpStats: any = '';
 
   ntpDataSource = new MatTableDataSource();
@@ -38,17 +40,17 @@
   dialogConfig = new MatDialogConfig();
 
   constructor(
-    private systemService: SystemService,
+    private _system: SystemService,
     private cdRef: ChangeDetectorRef,
-    private notification: NotificationService,
-    private confirmationService: Confirmation,
-    private formBuilder: FormBuilder,
+    private _notification: NotificationService,
+    private _confirmation: Confirmation,
+    private _fB: FormBuilder,
   ) {
     let result = {
       system_time: '2025-06-27T17:35:24'
     };
     const dateTime = new Date(result?.system_time);
-    this.dateTimeForm = this.formBuilder.group({
+    this.dateTimeForm = this._fB.group({
       systemDate: [dateTime, [Validators.required]],
       systemTime: ['', [Validators.required]],
       selectedParent: ['', Validators.required],
@@ -93,7 +95,7 @@
   }
 
   getSystemDateTime() {
-    this.systemService.getSystemDateTime()
+    this._system.getSystemDateTime()
       .pipe(take(1)).subscribe({
       next: (result: any) => {
         try {
@@ -107,13 +109,13 @@
             selectedGrandchild: tzParts[2] || '',
           });
         } catch (e) {
-          this.notification.showError('Failed to get the system date & time.');
+          this._notification.showError('Failed to get the system date & time.');
           console.error(e);
         }
         this.cdRef.detectChanges();
       },
       error: (error: any) => {
-        this.notification.showError(`Error: ${error?.message}`);
+        this._notification.showError(`Error: ${error?.message}`);
       }
     })
   }
@@ -170,27 +172,27 @@
     let payload: any = {system_time: formattedDateTime, system_timezone: fullTimezonePath};
     let rawPayload = new FormData();
     rawPayload.set('post_data', JSON.stringify(payload));
-    this.systemService.updateSystemDateTime(rawPayload)
+    this._system.updateSystemDateTime(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
           if (result && result.length > 1) {
             if (result[0]) {
-              this.notification.showSuccess(`System date & time updated successfully!`);
+              this._notification.showSuccess(`System date & time updated successfully!`);
               this.getSystemDateTime();
             } else {
-              this.notification.showError(`Failed to update system date & time.`);
+              this._notification.showError(`Failed to update system date & time.`);
             }
           }
         },
         error: () => {
-          this.notification.showError(`Failed to update system date & time.`);
+          this._notification.showError(`Failed to update system date & time.`);
         }
       })
   }
 
   getNTPConfig() {
-    this.systemService.getNTPConfig()
+    this._system.getNTPConfig()
       .pipe(take(1)).subscribe({
       next: (result: any) => {
         this.isNTPEnabled = result?.enable_ntp;
@@ -200,7 +202,7 @@
         this.cdRef.detectChanges();
       },
       error: error => {
-        this.notification.showError(`Error: ${error?.message}`);
+        this._notification.showError(`Error: ${error?.message}`);
       }
     })
   }
@@ -208,21 +210,21 @@
   onNTPToggleChange(event: any) {
     let rawPayload = new FormData();
     rawPayload.set('post_data', JSON.stringify({"enable_ntp": event?.checked}));
-    this.systemService.updateNTPStatus(rawPayload)
+    this._system.updateNTPStatus(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
           if (result && result.length > 1) {
             if (result[0]) {
-              this.notification.showSuccess(`NTP status updated successfully!`);
+              this._notification.showSuccess(`NTP status updated successfully!`);
               this.getNTPConfig();
             } else {
-              this.notification.showError(`Failed to update NTP: ${result[1]}`);
+              this._notification.showError(`Failed to update NTP: ${result[1]}`);
             }
           }
         },
         error: () => {
-          this.notification.showError('Failed to update NTP.');
+          this._notification.showError('Failed to update NTP.');
         }
       })
   }
@@ -238,7 +240,7 @@
 
   deleteNTPServer(server: any) {
     let confirmMsg = `Are you sure you want to delete "${server?.ip}"? This action cannot be undone.`
-    this.confirmationService.openConfirmDialog({
+    this._confirmation.openConfirmDialog({
       title: `Delete ${server?.host_ip}?`,
       message: confirmMsg,
       confirmButtonText: 'Yes, Delete It',
@@ -259,7 +261,7 @@
         }
         let rawPayload = new FormData();
         rawPayload.set('pk', JSON.stringify(payload));
-        this.systemService.deleteNTPServer(rawPayload)
+        this._system.deleteNTPServer(rawPayload)
           .pipe(take(1))
           .subscribe({
             next: (result: any) => {
@@ -269,15 +271,15 @@
             error: (err: any) => {
               if (err?.status === 200) {
                 // ToDo: Backend fix required.
-                this.notification.showSuccess(`${server?.ip} deleted successfully!`);
+                this._notification.showSuccess(`${server?.ip} deleted successfully!`);
                 this.getNTPConfig();
               } else {
-                this.notification.showError('Deletion Failed.');
+                this._notification.showError('Deletion Failed.');
               }
             }
           })
       } else {
-        this.notification.showSuccess('Deletion cancelled.');
+        this._notification.showSuccess('Deletion cancelled.');
       }
     });
   }
@@ -303,8 +305,8 @@
   ]
 
   constructor(
-    private formBuilder: FormBuilder, private systemService: SystemService, private notification: NotificationService,) {
-    this.ntpServerForm = this.formBuilder.group({
+    private _fB: FormBuilder, private _system: SystemService, private _notification: NotificationService,) {
+    this.ntpServerForm = this._fB.group({
       type: ['v4', [Validators.required]],
       ip: ['', [Validators.required]],
       version: [4, [Validators.required]],
@@ -344,21 +346,21 @@
     }
     let rawPayload = new FormData();
     rawPayload.set('post_data', JSON.stringify(payload));
-    this.systemService.addNTPServer(rawPayload)
+    this._system.addNTPServer(rawPayload)
       .pipe(take(1))
       .subscribe({
         next: (result: any) => {
           if (result && result.length > 1) {
             if (result[0]) {
-              this.notification.showSuccess(`${this.ntpServerForm.value.ip} added successfully!`);
+              this._notification.showSuccess(`${this.ntpServerForm.value.ip} added successfully!`);
               this.dialogRef.close(true);
             } else {
-              this.notification.showError(`Failed to add the host - ${this.ntpServerForm.value.ip}`);
+              this._notification.showError(`Failed to add the host - ${this.ntpServerForm.value.ip}`);
             }
           }
         },
         error: () => {
-          this.notification.showError('Failed to add the host.');
+          this._notification.showError('Failed to add the host.');
         }
       })
   }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/user-management/user-management.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/user-management/user-management.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/user-management/user-management.html	(working copy)
@@ -7,7 +7,7 @@
   <table mat-table [dataSource]="userDataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef>Id.</th>
-      <td mat-cell *matCellDef="let element; let i = index;">{{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;">{{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="username">
       <th mat-header-cell *matHeaderCellDef>Username</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/user-management/user-management.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/user-management/user-management.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/user-management/user-management.ts	(working copy)
@@ -10,10 +10,11 @@
 import {CustomValidators} from '../../../utils/custom-validators';
 import {MatPaginator} from '@angular/material/paginator';
 import {MatTableDataSource} from '@angular/material/table';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-user-management',
-  imports: [SharedModule,],
+  imports: [SharedModule, GlobalSerialPipe,],
   templateUrl: './user-management.html',
   styleUrl: './user-management.scss'
 })
@@ -63,13 +64,6 @@
         this.cdRef.detectChanges();
       }
     });
-  }
-
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
   }
 
   getRoles() {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resource-groups/vpn-acl-resource-groups.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resource-groups/vpn-acl-resource-groups.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resource-groups/vpn-acl-resource-groups.html	(working copy)
@@ -9,7 +9,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="groupName">
       <th mat-header-cell *matHeaderCellDef> Group Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resource-groups/vpn-acl-resource-groups.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resource-groups/vpn-acl-resource-groups.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resource-groups/vpn-acl-resource-groups.ts	(working copy)
@@ -11,10 +11,11 @@
 import {Subscription} from 'rxjs';
 import {Confirmation} from '../../../services/confirmation';
 import {DeviceService} from '../../../services/device-service';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-vpn-acl-resource-groups',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './vpn-acl-resource-groups.html',
   styleUrl: './vpn-acl-resource-groups.scss'
 })
@@ -116,13 +117,6 @@
         this._notification.showError(`Error: ${error?.message}`);
       }
     })
-  }
-
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
   }
 
   addACLResourceGroup() {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resources/vpn-acl-resources.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resources/vpn-acl-resources.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resources/vpn-acl-resources.html	(working copy)
@@ -9,7 +9,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="resource">
       <th mat-header-cell *matHeaderCellDef> Resource</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resources/vpn-acl-resources.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resources/vpn-acl-resources.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-resources/vpn-acl-resources.ts	(working copy)
@@ -10,11 +10,13 @@
 import {Confirmation} from '../../../services/confirmation';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {CustomValidators} from '../../../utils/custom-validators';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-vpn-acl-resources',
   imports: [
-    SharedModule
+    SharedModule,
+    GlobalSerialPipe
   ],
   templateUrl: './vpn-acl-resources.html',
   styleUrl: './vpn-acl-resources.scss'
@@ -86,13 +88,6 @@
     });
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   addACLResource() {
     this.dialogConfig.data = {
       serviceName: this.serviceName,
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-rules/vpn-acl-rules.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-rules/vpn-acl-rules.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-rules/vpn-acl-rules.html	(working copy)
@@ -9,7 +9,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="type">
       <th mat-header-cell *matHeaderCellDef> Target Type</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-rules/vpn-acl-rules.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-rules/vpn-acl-rules.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-acl-rules/vpn-acl-rules.ts	(working copy)
@@ -9,11 +9,13 @@
 import {take} from 'rxjs/operators';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {Confirmation} from '../../../services/confirmation';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-vpn-acl-rules',
   imports: [
-    SharedModule
+    SharedModule,
+    GlobalSerialPipe
   ],
   templateUrl: './vpn-acl-rules.html',
   styleUrl: './vpn-acl-rules.scss'
@@ -91,13 +93,6 @@
     });
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   addACLRule() {
     this.dialogConfig.data = {
       serviceName: this.serviceName,
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-hardware-id/vpn-hardware-id.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-hardware-id/vpn-hardware-id.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-hardware-id/vpn-hardware-id.html	(working copy)
@@ -9,7 +9,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="category">
       <th mat-header-cell *matHeaderCellDef> Category</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-hardware-id/vpn-hardware-id.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-hardware-id/vpn-hardware-id.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-hardware-id/vpn-hardware-id.ts	(working copy)
@@ -11,11 +11,13 @@
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {Subscription} from 'rxjs';
 import {DeviceService} from '../../../services/device-service';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-vpn-hardware-id',
   imports: [
     SharedModule,
+    GlobalSerialPipe,
   ],
   templateUrl: './vpn-hardware-id.html',
   styleUrl: './vpn-hardware-id.scss'
@@ -157,13 +159,6 @@
     return post_data;
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   approveHardwareId(_config: any) {
     let confirmMsg = `Are you sure you want to approve it - ${_config?.name}?`
     this._confirmation.openConfirmDialog({
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-resource-groups/vpn-resource-groups.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-resource-groups/vpn-resource-groups.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-resource-groups/vpn-resource-groups.html	(working copy)
@@ -9,7 +9,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="name">
       <th mat-header-cell *matHeaderCellDef> Group Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-resource-groups/vpn-resource-groups.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-resource-groups/vpn-resource-groups.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/vpn-resource-groups/vpn-resource-groups.ts	(working copy)
@@ -10,11 +10,13 @@
 import {take} from 'rxjs/operators';
 import {FormBuilder, FormGroup, Validators} from '@angular/forms';
 import {DeviceService} from '../../../services/device-service';
+import {GlobalSerialPipe} from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-vpn-resource-groups',
   imports: [
-    SharedModule
+    SharedModule,
+    GlobalSerialPipe
   ],
   templateUrl: './vpn-resource-groups.html',
   styleUrl: './vpn-resource-groups.scss'
@@ -130,13 +132,6 @@
     });
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   goToDetails(_group: any) {
     this._router.navigate(['/device/ssl-vpn/details/vpn-resource', this.deviceName, this.serviceName, _group?.group_name], {
       state: {}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/upgrade-centre/upgrade-centre.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/upgrade-centre/upgrade-centre.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/upgrade-centre/upgrade-centre.html	(working copy)
@@ -10,7 +10,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="buildName">
       <th mat-header-cell *matHeaderCellDef> Build Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/upgrade-centre/upgrade-centre.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/upgrade-centre/upgrade-centre.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/upgrade-centre/upgrade-centre.ts	(working copy)
@@ -10,10 +10,11 @@
 import {Confirmation} from '../../services/confirmation';
 import {SystemService} from '../../services/system-service';
 import {Subject} from 'rxjs';
+import {GlobalSerialPipe} from '../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-upgrade-centre',
-  imports: [SharedModule,],
+  imports: [SharedModule, GlobalSerialPipe,],
   templateUrl: './upgrade-centre.html',
   styleUrl: './upgrade-centre.scss'
 })
@@ -55,13 +56,6 @@
         this._notification.showError(`Error: ${error?.message}`);
       }
     })
-  }
-
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
   }
 
   updateMD5(_build: any) {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/vpn-management/vpn-management.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/vpn-management/vpn-management.html	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/vpn-management/vpn-management.html	(working copy)
@@ -7,7 +7,7 @@
   <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
-      <td mat-cell *matCellDef="let element; let i = index;"> {{ getGlobalSerial(i) }}</td>
+      <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
     </ng-container>
     <ng-container matColumnDef="serviceName">
       <th mat-header-cell *matHeaderCellDef> Service Name</th>
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/vpn-management/vpn-management.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/vpn-management/vpn-management.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/vpn-management/vpn-management.ts	(working copy)
@@ -8,10 +8,11 @@
 import {NotificationService} from '../../services/notification';
 import {DeviceService} from '../../services/device-service';
 import {Router} from '@angular/router';
+import {GlobalSerialPipe} from '../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-vpn-management',
-  imports: [SharedModule],
+  imports: [SharedModule, GlobalSerialPipe],
   templateUrl: './vpn-management.html',
   styleUrl: './vpn-management.scss'
 })
@@ -164,13 +165,6 @@
     return result;
   }
 
-  getGlobalSerial(index: number): number {
-    if (this.paginator) {
-      return this.paginator.pageIndex * this.paginator.pageSize + index + 1;
-    }
-    return index + 1;
-  }
-
   goToDetails(vsite: any) {
     this.selectedVSite = vsite;
     this._router.navigate(['/device/ssl-vpn/details', vsite?.device_name, vsite?.name], {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/constants/api_urls.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/constants/api_urls.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/constants/api_urls.ts	(working copy)
@@ -179,4 +179,6 @@
   GET_AVX_INSTANCE_PLATFORM_RESOURCES_URL: `${PREFIX}/proxy_req_dev/api/avx/va/instance/VAInstance/_field_group/va_name/`,
   GET_AVX_VA_INSTANCE_BASIC_CONFIG_URL: `${PREFIX}/proxy_req_dev/va_basic_config_by_va_run`,
   GET_AVX_VA_INSTANCE_SHOW_VERSION_URL: `${PREFIX}/proxy_req_dev/api/avx/va/instance/ShowVAVersion/_get_asso_list_data`,
+  // OpenSearch
+  GET_LOGS_FROM_OPENSEARCH_URL: `${PREFIX}/log-analysis/search`,
 } as const; // Makes properties readonly
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/constants/menu.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/constants/menu.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/constants/menu.ts	(working copy)
@@ -229,23 +229,10 @@
   {
     label: 'Log Analysis',
     icon: '',
+    routerLink: '/log-analysis',
     expanded: false,
-    children: [
-      {
-        label: 'SSL Services',
-        icon: '',
-        routerLink: '/log-analysis/ssl',
-        roles: ['super_admin', 'device_admin', 'common_admin'],
-        permissions: ['lSSL']
-      },
-      {
-        label: 'SSL VPN Services',
-        icon: '',
-        routerLink: '/log-analysis/vpn',
-        roles: ['super_admin', 'device_admin', 'common_admin'],
-        permissions: ['lVPN']
-      }
-    ]
+    roles: ['super_admin', 'device_admin', 'common_admin'],
+    permissions: ['lSSL']
   },
   {
     label: 'Observability',
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/device-service.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/device-service.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/device-service.ts	(working copy)
@@ -119,6 +119,11 @@
     return this.http.get(URLS.GET_APV_VIRTUAL_SERVICES_URL);
   }
 
+  getAPVSLBVirtualServices(deviceId: string) {
+    return this.http.get(`${URLS.GET_APV_VIRTUAL_SERVICES_URL}`, {},
+      [{name: 'Cm-Data', value: deviceId}, {name: 'Cm-Type', value: 'device'}]);
+  }
+
   getScheduleDeviceBackup() {
     return this.http.get(URLS.GET_SCHEDULE_DEVICE_BACKUP_URL);
   }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/open-search.spec.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/open-search.spec.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/open-search.spec.ts	(working copy)
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { OpenSearch } from './open-search';
+
+describe('OpenSearch', () => {
+  let service: OpenSearch;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(OpenSearch);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/open-search.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/open-search.ts	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/open-search.ts	(working copy)
@@ -0,0 +1,20 @@
+import {Injectable} from '@angular/core';
+import {HttpService} from './http';
+import {URLS} from '../constants/api_urls';
+
+@Injectable({
+  providedIn: 'root'
+})
+export class OpenSearch {
+
+  constructor(private http: HttpService) {
+  }
+
+  queryOSLogs(rawPayload: any) {
+    return this.http.post(URLS.GET_LOGS_FROM_OPENSEARCH_URL, rawPayload, {
+      csrf: true,
+      isFormData: true,
+      csrfInFormData: true
+    });
+  }
+}
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/shared/shared-module.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/shared/shared-module.ts	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/shared/shared-module.ts	(working copy)
@@ -83,6 +83,14 @@
 import {MatPaginatorModule} from '@angular/material/paginator';
 import {NgxEchartsModule} from 'ngx-echarts';
 import {MatProgressBarModule} from '@angular/material/progress-bar';
+import {
+  NgxMatDatepickerActions,
+  NgxMatDatepickerApply,
+  NgxMatDatepickerCancel,
+  NgxMatDatepickerClear,
+  NgxMatDatepickerInput,
+  NgxMatDatetimepicker,
+} from '@ngxmc/datetime-picker';
 
 @NgModule({
   declarations: [],
@@ -115,6 +123,13 @@
     NgxEchartsModule,
     MatExpansionModule,
     MatProgressBarModule,
+    NgxMatDatepickerActions,
+    NgxMatDatepickerActions,
+    NgxMatDatepickerApply,
+    NgxMatDatepickerCancel,
+    NgxMatDatepickerClear,
+    NgxMatDatepickerInput,
+    NgxMatDatetimepicker,
   ],
   exports: [
     CommonModule,
@@ -144,6 +159,13 @@
     NgxEchartsModule,
     MatExpansionModule,
     MatProgressBarModule,
+    NgxMatDatepickerActions,
+    NgxMatDatepickerActions,
+    NgxMatDatepickerApply,
+    NgxMatDatepickerCancel,
+    NgxMatDatepickerClear,
+    NgxMatDatepickerInput,
+    NgxMatDatetimepicker,
   ]
 })
 export class SharedModule {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/styles.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/styles.scss	(revision 2701)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/styles.scss	(working copy)
@@ -173,6 +173,12 @@
   font-weight: 500;
   min-width: 150px; /* Give the label a minimum width for consistent alignment */
   text-align: right; /* Align label text to the right */
+}
+
+.form-label-1 {
+  min-width: 60px;
+  font-weight: 500;
+  text-align: right;
 }
 
 /* Optional: Adjust the width of the mat-form-field if necessary */
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/hive/an_opensearch.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/hive/an_opensearch.py	(nonexistent)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/hive/an_opensearch.py	(working copy)
@@ -0,0 +1,20 @@
+from opensearchpy import OpenSearch
+from django.http import HttpResponse
+import json
+
+HOST = 'localhost'
+PORT = 9200
+AUTH = ('admin', 'Arr@y2050')
+
+
+def opensearch_proxy(request):
+    client = OpenSearch(
+        hosts=[{'host': HOST, 'port': PORT}],
+        http_auth=AUTH,
+        use_ssl=True,
+        verify_certs=False,
+        ssl_assert_hostname=False,
+        ssl_show_warn=False,
+    )
+    res = client.search(index='acm-*', body=json.loads(request.body), request_timeout=300)
+    return HttpResponse(json.dumps(res), content_type='application/json')
Index: /branches/amp_4_0/tools/requirements.txt
===================================================================
--- /branches/amp_4_0/tools/requirements.txt	(revision 2701)
+++ /branches/amp_4_0/tools/requirements.txt	(working copy)
@@ -43,3 +43,4 @@
 urllib3==1.22
 Whoosh==2.7.4
 yum-metadata-parser==1.1.4
+opensearch-py==3.0.0
\ No newline at end of file
