Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/libbasic_operation.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/libbasic_operation.py	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/lib/libbasic_operation.py	(working copy)
@@ -336,10 +336,9 @@
             else:
                 username = "system"
         s_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
-        insert_sql = "insert into operation_log(username, client_ip, time, level, module, operation) values('%s', '%s', '%s', '%s', '%s', '%s')" % (
-            username, ip, s_time, level, module, operation)
+        insert_sql = "insert into operation_log(username, client_ip, time, level, module, operation) values(%s, %s, %s, %s, %s, %s)"
         db = DB.get_connected_db()
-        db.execute_sql(insert_sql)
+        db.execute_sql(insert_sql, (username, ip, s_time, level, module, operation))
         db.close()
         log_msg = "%s level=%s, username=%s, client_ip=%s, module=%s, message=\"%s\"" % (s_time, level, username, ip,
                                                                                          module, operation)
@@ -354,10 +353,9 @@
             request_msg += " %s" % post_data
         result_msg = "success" if result["result"] else "failed, %s" % json.dumps(result["msg"])
         operation = "Process RESTful API request: %s, result: %s" % (request_msg, result_msg)
-        insert_sql = "insert into operation_log(username, client_ip, time, level, module, operation) values('%s', '%s', '%s', '%s', '%s', '%s')" % (
-            username, ip, s_time, level, "API", operation)
+        insert_sql = "insert into operation_log(username, client_ip, time, level, module, operation) values(%s, %s, %s, %s, %s, %s)"
         db = DB.get_connected_db()
-        db.execute_sql(insert_sql)
+        db.execute_sql(insert_sql, (username, ip, s_time, level, "API", operation))
         db.close()
         log_msg = "%s level=%s, username=%s, client_ip=%s, module=API, message=\"%s\"" % (s_time, level, username, ip,
                                                                                           operation)
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/configuration/config_file/__init__.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/configuration/config_file/__init__.py	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/configuration/config_file/__init__.py	(working copy)
@@ -6,7 +6,7 @@
 import os
 
 from apscheduler.schedulers.background import BackgroundScheduler
-from django.db.models.query import QuerySet
+
 from django.utils.translation import gettext_lazy as _
 
 from cm.lib.AG_CLI_TABLE import get_delete_cli
@@ -23,47 +23,48 @@
 from hive.model.action import Action
 from hive.model.fields import *
 from hive.model.manager import CLIManager
+from hive.model.query import mark_expire_all, QuerySet
 
 __ = _
 """
 class FileType(ANModel):
-    name = CharField(verbose_name='File Type', primary_key=True, length='1..32')
-    asso = AssoField2(verbose_name='Config File', tgt='configuration.config_file.ConfigFile.asso_file_type', 
-        mul='1', pos='left', hidden=True, optional=True)
+name = CharField(verbose_name='File Type', primary_key=True, length='1..32')
+asso = AssoField2(verbose_name='Config File', tgt='configuration.config_file.ConfigFile.asso_file_type',
+mul='1', pos='left', hidden=True, optional=True)
 
-    class Meta:
-        verbose_name = 'File Type'
-        show_im_export_button = False
-        list_config_options={
-            'click_enable':False}
+class Meta:
+verbose_name = 'File Type'
+show_im_export_button = False
+list_config_options={
+'click_enable':False}
 
-    class Manager(CLIManager):
-        def _insert(self, instance):
-            data = instance.get_field_dict()
-            db = DB.get_connected_db()
-            save_sql = "INSERT INTO file_type(name) values('%s')" % data['name']
-            db.execute_sql(save_sql)
-            db.close()
-            return
-        def _delete_instance(self, instance):
-            data = instance.get_field_dict()
-            if data['name'] == 'device' or data['name'] == 'command' or data['name'] == 'diff':
-                raise ModelQueryException(CLICmdError(__('Sorry you can not remove the device, diff and command type!')))
-            db = DB.get_connected_db()
-            delete_sql = "DELETE FROM file_type where name='%s' " % data['name']
-            db.execute_sql(delete_sql)
-            db.close()
-            return
-        def _get_query_set(self):
-            db = DB.get_connected_db()
-            fetchall_sql = "SELECT * FROM file_type"
-            data = db.fetchall(fetchall_sql)
-            db.close()
-            key = ['name']
-            result = [dict(zip(key, each)) for each in data]
-            for each in result:
-                self._model._meta.mark_delay_query(each)
-            return QuerySet(self._model, result)
+class Manager(CLIManager):
+def _insert(self, instance):
+data = instance.get_field_dict()
+db = DB.get_connected_db()
+save_sql = "INSERT INTO file_type(name) values('%s')" % data['name']
+db.execute_sql(save_sql)
+db.close()
+return
+def _delete_instance(self, instance):
+data = instance.get_field_dict()
+if data['name'] == 'device' or data['name'] == 'command' or data['name'] == 'diff':
+raise ModelQueryException(CLICmdError(__('Sorry you can not remove the device, diff and command type!')))
+db = DB.get_connected_db()
+delete_sql = "DELETE FROM file_type where name='%s' " % data['name']
+db.execute_sql(delete_sql)
+db.close()
+return
+def _get_query_set(self):
+db = DB.get_connected_db()
+fetchall_sql = "SELECT * FROM file_type"
+data = db.fetchall(fetchall_sql)
+db.close()
+key = ['name']
+result = [dict(zip(key, each)) for each in data]
+for each in result:
+self._model._meta.mark_delay_query(each)
+return QuerySet(self._model, result)
 """
 
 
@@ -135,11 +136,11 @@
                                                                                '__field:cm.device_mgmt.device.Device.name'])
             }),
             EnumField(verbose_name='Option', default='immediate', name='option', values=(
-                ('immediate', 'Immediate'), ('deferred', 'Deferred'), ('loop', 'Loop')
-            )),
+                          ('immediate', 'Immediate'), ('deferred', 'Deferred'), ('loop', 'Loop')
+                      )),
             EnumField(verbose_name='Scope', optional=True, default='global', name='scope', values=(
-                ('global', 'Global'), ('vs', 'VS')
-            )),
+                          ('global', 'Global'), ('vs', 'VS')
+                      )),
             DateTimeField(verbose_name='Expire Time', name='expire_time',
                           condition=ValueCondition('option', ['deferred'])),
             CharField(name='loop_time', verbose_name='Loop time(Seconds)',
@@ -162,15 +163,15 @@
             DynamicMultiEnumField(name='device', verbose_name='devices',
                                   values=['__field:cm.device_mgmt.device.Device.name']),
             EnumField(name='module', verbose_name='Module', values=(
-                ('all', 'All'),
-                ('custom', 'Custom'))),
+                          ('all', 'All'),
+                          ('custom', 'Custom'))),
             CharField(name='custom', verbose_name='Custom Value', optional=True, length='1..128',
                       condition=ValueCondition('module', ['custom'])),
             CharField(name='vsite_name', verbose_name='Vsite Name', length='1..64',
                       condition=ValueCondition('module', ['custom'])),
             EnumField(verbose_name='Option', default='immediate', name='option', values=(
-                ('immediate', 'Immediate'), ('deferred', 'Deferred'), ('loop', 'Loop')
-            )),
+                          ('immediate', 'Immediate'), ('deferred', 'Deferred'), ('loop', 'Loop')
+                      )),
             DateTimeField(verbose_name='Expire Time', name='expire_time',
                           condition=ValueCondition('option', ['deferred'])),
             CharField(name='loop_time', verbose_name='Loop time(Seconds)', condition=ValueCondition('option', ['loop']))
@@ -216,8 +217,8 @@
             DynamicMultiEnumField(name='device', verbose_name='devices',
                                   values=['__field:cm.device_mgmt.device.Device.name']),
             EnumField(verbose_name='Option', default='immediate', name='option', values=(
-                ('immediate', 'Immediate'), ('deferred', 'Deferred'),
-            )),
+                          ('immediate', 'Immediate'), ('deferred', 'Deferred'),
+                      )),
             DateTimeField(verbose_name='Expire Time', name='expire_time',
                           condition=ValueCondition('option', ['deferred'])),
         )
@@ -279,11 +280,11 @@
             }),
             IntegerField(name='interval', verbose_name='Interval', optional=True),
             EnumField(name='unit', verbose_name='Unit', optional=True, default='days', values=(
-                ('seconds', 'Seconds'),
-                ('minutes', 'Minutes'),
-                ('hours', 'Hours'),
-                ('days', 'Days'),
-                ('weeks', 'Weeks'))
+                          ('seconds', 'Seconds'),
+                          ('minutes', 'Minutes'),
+                          ('hours', 'Hours'),
+                          ('days', 'Days'),
+                          ('weeks', 'Weeks'))
                       )
         )
 
@@ -299,15 +300,15 @@
         instance_mul = '0'
         option_fields = (
             EnumField(name='module', verbose_name='Module', values=(
-                ('all', 'All'),
-                ('custom', 'Custom'))),
+                          ('all', 'All'),
+                          ('custom', 'Custom'))),
             CharField(name='custom', verbose_name='Custom Value', optional=True, length='1..128',
                       condition=ValueCondition('module', ['custom'])),
             CharField(name='vsite_name', verbose_name='Vsite Name', length='1..64',
                       condition=ValueCondition('module', ['custom'])),
             EnumField(verbose_name='Option', default='immediate', name='option', values=(
-                ('immediate', 'Immediate'), ('deferred', 'Deferred'), ('loop', 'Loop')
-            )),
+                          ('immediate', 'Immediate'), ('deferred', 'Deferred'), ('loop', 'Loop')
+                      )),
             DateTimeField(verbose_name='Expire Time', name='expire_time',
                           condition=ValueCondition('option', ['deferred'])),
             CharField(name='loop_time', verbose_name='Loop time(Seconds)', condition=ValueCondition('option', ['loop']))
@@ -337,10 +338,10 @@
             key = ['name', 'create_time', 'modify_time', 'file_type', 'comment', 'device_type']
             result = [dict(zip(key, each)) for each in data]
             """
-            for each in result:
-                each['asso_file_type'] = [{'name':each['type']}]
-                del each['type']
-                #self._model._meta.mark_delay_query(each)
+for each in result:
+each['asso_file_type'] = [{'name':each['type']}]
+del each['type']
+#self._model._meta.mark_delay_query(each)
             """
             res = sorted(result, key=lambda x: x["create_time"], reverse=True)
             return QuerySet(self._model, res)
@@ -414,7 +415,7 @@
                         local_ip = get_ip_address(network_card)
                     except Exception as e:
                         raise ModelQueryException(CLICmdError(
-                            __('Local network settings are abnormal. Please configuare management interface by CLI "system management intertface <port_name>".')))
+                                                      __('Local network settings are abnormal. Please configuare management interface by CLI "system management intertface <port_name>".')))
 
                     cli_url = '"ftp://array:admin@%s:9993/upload/%s/%s"' % (local_ip, task_name, filename)
 
@@ -552,6 +553,7 @@
 
         def _perform_Onekey_Backup(self, options):
             from cm.lib.task_scheduler import add_job_into_database, remove_job_from_database, config_backup
+            from cm.models.device_mgmt.device import get_rest_info_from_device
             from cm.lib.task_scheduler import TaskScheduler
             TASK = TaskScheduler()
             result = []
@@ -565,7 +567,7 @@
                 else:
                     result = options["devices"]["device"]
             else:
-                group_list = options['devices'].values()[0]
+                group_list = list(options['devices'].values())[0]
                 db = DB.get_connected_db()
                 for group in group_list:
                     select_sql = "SELECT name FROM device WHERE device_group = '%s'" % group
@@ -810,7 +812,7 @@
             return
 
         def _perform_Init_device(self, options):
-            from cm.lib.task_scheduler import config_init_device, remove_job_from_database
+            from cm.lib.task_scheduler import config_init_device, remove_job_from_database, add_job_into_database
             from cm.models.device_mgmt.device import get_rest_info_from_device
             from cm.lib.task_scheduler import TaskScheduler
             TASK = TaskScheduler()
@@ -824,7 +826,7 @@
                     db.close()
                     device_list = [each[0] for each in data]
                 else:
-                    group_list = options['devices'].values()[0]
+                    group_list = list(options['devices'].values())[0]
                     db = DB.get_connected_db()
                     for group in group_list:
                         select_sql = "SELECT name FROM device WHERE device_group = '%s'" % group
@@ -843,7 +845,7 @@
                     db.close()
                     device_list = [each[0] for each in data]
                 else:
-                    device_list = options['devices'].values()[0]
+                    device_list = list(options['devices'].values())[0]
 
             # options {u'device': u'\u64ce\u5929\u67f1', u'__pk_list': [{u'asso_file_type': [{u'_asso_idx': 0, u'name': u'test'}], u'name': u'\u6d4b\u8bd5'}]}
             if pk_list['file_type'] != 'system' and pk_list['file_type'] != 'customize' and pk_list[
@@ -862,8 +864,8 @@
 
             if date < date_now:
                 raise ModelQueryException(CLICmdError(
-                    __('Time(%s) has passed, Now %s' % (date.strftime('%Y-%m-%d %H:%M:%S'),
-                                                        date_now.strftime('%Y-%m-%d %H:%M:%S')))))
+                                              __('Time(%s) has passed, Now %s' % (date.strftime('%Y-%m-%d %H:%M:%S'),
+                                                                                  date_now.strftime('%Y-%m-%d %H:%M:%S')))))
 
             for device in device_list:
                 if type(device) == list:
@@ -899,7 +901,7 @@
         def check_config_from_device(self, file_name, diff_file_path, task_name, options, file_type,
                                      source_deivce=None):
             from cm.lib.task_scheduler import add_job_into_database, remove_job_from_database, config_compliance_check, \
-                config_compliance_check_all
+            config_compliance_check_all
             from cm.lib.task_scheduler import TaskScheduler
             TASK = TaskScheduler()
             if not os.path.exists(os.path.dirname(diff_file_path)):
@@ -912,8 +914,8 @@
 
             if options['option'] != 'loop' and date < datetime.datetime.now():
                 raise ModelQueryException(CLICmdError(
-                    __('Time(%s) has passed, Now %s' % (date.strftime('%Y-%m-%d %H:%M:%S'),
-                                                        datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))))
+                                              __('Time(%s) has passed, Now %s' % (date.strftime('%Y-%m-%d %H:%M:%S'),
+                                                                                  datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))))
 
             if TASK.get_schedule(task_name):
                 TASK.remove(task_name)
@@ -1014,7 +1016,7 @@
 
         def _perform_Custom_Compliance_check(self, options):
             from cm.lib.task_scheduler import add_job_into_database, remove_job_from_database, \
-                config_compliance_check_custom, config_summary_diff
+            config_compliance_check_custom, config_summary_diff
             from cm.lib.task_scheduler import TaskScheduler
             TASK = TaskScheduler()
             file_type = "backup"
@@ -1027,7 +1029,7 @@
             if target_type == 'batch':
                 device_list = []
                 if 'group' in options['devices']:
-                    group_list = options['devices'].values()[0]
+                    group_list = list(options['devices'].values())[0]
                     db = DB.get_connected_db()
                     for group in group_list:
                         select_sql = "SELECT name FROM device WHERE device_group = '%s'" % group
@@ -1041,7 +1043,7 @@
                             device_list += each_device_list
                     db.close()
                 else:
-                    device_list = options['devices'].values()[0]
+                    device_list = list(options['devices'].values())[0]
 
                 db = DB.get_connected_db()
                 for each in device_list:
@@ -1156,7 +1158,7 @@
             return
 
         def _perform_Batch_CLI(self, options):
-            from cm.lib.task_scheduler import add_job_into_database, config_batch_cli
+            from cm.lib.task_scheduler import add_job_into_database, config_batch_cli, remove_job_from_database
             from cm.models.device_mgmt.device import get_rest_info_from_device
             from cm.lib.task_scheduler import TaskScheduler
             TASK = TaskScheduler()
@@ -1176,8 +1178,8 @@
 
             if date < datetime.datetime.now():
                 raise ModelQueryException(CLICmdError(
-                    __('Time(%s) has passed, Now %s' % (date.strftime('%Y-%m-%d %H:%M:%S'),
-                                                        datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))))
+                                              __('Time(%s) has passed, Now %s' % (date.strftime('%Y-%m-%d %H:%M:%S'),
+                                                                                  datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')))))
             for device in options['device']:
                 time.sleep(1)
                 date_now = datetime.datetime.now()
@@ -1221,10 +1223,10 @@
             key = ['id', 'name', 'vsite_name']
             result = [dict(zip(key, each)) for each in data]
             """
-            for each in result:
-                each['asso_file_type'] = [{'name':each['type']}]
-                del each['type']
-                #self._model._meta.mark_delay_query(each)
+for each in result:
+each['asso_file_type'] = [{'name':each['type']}]
+del each['type']
+#self._model._meta.mark_delay_query(each)
             """
             return QuerySet(self._model, result)
 
@@ -1249,9 +1251,9 @@
             key = ['name, device_type, content, create_time, modify_time, note']
             result = [dict(zip(key, each)) for each in data]
             """
-            for each in result:
-                each['asso_file_type'] = [{'name':each['type']}]
-                del each['type']
-                #self._model._meta.mark_delay_query(each)
+for each in result:
+each['asso_file_type'] = [{'name':each['type']}]
+del each['type']
+#self._model._meta.mark_delay_query(each)
             """
             return QuerySet(self._model, result)
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/device_mgmt/device/__init__.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/device_mgmt/device/__init__.py	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/models/device_mgmt/device/__init__.py	(working copy)
@@ -16,7 +16,7 @@
 from cm.lib.communication import send_https_rest_request, modify_url, L
 from cm.lib.elk import get_elk
 from cm.lib.libbasic_operation import send_command_to_device, send_cli_to_device, insert_default_tmpkey, \
-    delete_all_tmpkey, ping_device
+delete_all_tmpkey, ping_device
 from cm.lib.postgres_db import DB
 from cm.lib.task_scheduler import add_job_into_database, remove_job_from_database, config_backup
 from cm.models.audit.user.user_body import body_login_detail, body_device_vsite
@@ -130,21 +130,21 @@
         'restapi_account': GroupField(verbose_name='RESTful API Account', editable=True,
                                       custom_display=lambda val: 'username: ' + val[
                                           'restapi_username'] + '<br>password: ********', fields={
-                'restapi_username': CharField(verbose_name='Username', length='1..16'),
-                'restapi_password': PasswordField(verbose_name='Password', length='1..32')
-            }),
+                                          'restapi_username': CharField(verbose_name='Username', length='1..16'),
+                                          'restapi_password': PasswordField(verbose_name='Password', length='1..32')
+                                      }),
         'console_account': GroupField(verbose_name='Web Console Account', editable=True,
                                       custom_display=lambda val: 'username: ' + val[
                                           'console_username'] + '<br>password: ********', fields={
-                'console_username': CharField(verbose_name='Username', length='1..16'),
-                'console_password': PasswordField(verbose_name='Password', length='1..32')
-            }),
+                                          'console_username': CharField(verbose_name='Username', length='1..16'),
+                                          'console_password': PasswordField(verbose_name='Password', length='1..32')
+                                      }),
         'connection': BooleanField(verbose_name='Connection', editable=False, configurable=False,
                                    display=('connection', 'unconnection'), optional=True),
         'status': BooleanField(verbose_name='Status', configurable=False, editable=False, display=('new', 'active'),
                                optional=True),
         'log_enable': BooleanField(verbose_name='Collection Log', display=('enable', 'disable'), default=False),
-        # 'snmp_enable' : BooleanField(verbose_name='Collection SNMP', display=('enable', 'disable'), default=False), 
+        # 'snmp_enable' : BooleanField(verbose_name='Collection SNMP', display=('enable', 'disable'), default=False),
         'snmp_general': GroupField(verbose_name='SNMP General', optional=True, editable=True, fields={
             'snmp_enable': BooleanField(verbose_name='SNMP Enable'),
             'community': CharField(verbose_name='Community', optional=True)
@@ -354,6 +354,12 @@
                     each['status'] = False
                 if each['license_key'] == 'None':
                     each['license_key'] = ''
+                # Initialize version fields with defaults
+                for field in ['host_name', 'system_cpu', 'system_ram', 'system_boot_time', 'system_up_time',
+                              'platform_bld_date', 'ssl_hw', 'compression_hw', 'network_interface', 'model',
+                              'serial_number', 'license_feature', 'license_date', 'build_version', 'license_limit']:
+                    each[field] = ''
+
                 if each['version']:
                     replace_result = each['version'].replace('\\n', '\n')
                     rtn = cli_parse(replace_result, [
@@ -540,7 +546,7 @@
 
             if self.check_ip_name_from_device(data['ip'], data.get('name')):
                 raise ModelQueryException(CLICmdError(__('Sorry IP or Name has exists.')))
-            
+
             # Extract IP string from dictionary if needed
             ip_addr = list(data['ip'].values())[0] if isinstance(data['ip'], dict) else data['ip']
             L.add_lock(ip_addr)
@@ -563,9 +569,9 @@
             except Exception as e:
                 if 'timed out' in str(e):
                     raise ModelQueryException(CLICmdError(
-                        __('Register timed out! Please check the ip address and make sure the device have already turned on the RESTful API service and the RESTful API port is correct!')))
+                                                  __('Register timed out! Please check the ip address and make sure the device have already turned on the RESTful API service and the RESTful API port is correct!')))
                 if data.get('type') in OTHER_CATEGORY_LIST:
-                     raise ModelQueryException(CLICmdError(__('Register Failed. Device is unreachable.')))
+                    raise ModelQueryException(CLICmdError(__('Register Failed. Device is unreachable.')))
                 raise ModelQueryException(CLICmdError(__('Register Failed.')))
             else:
                 if data.get('protocol') == 'xmlrpc':
@@ -585,10 +591,10 @@
                         data['version'] = rest_body['SystemInfo']['version']
                     elif rest_response_data['status'] == 401:
                         raise ModelQueryException(CLICmdError(
-                            __('Register Failed! Please make sure the RESTful API username/password is correct!')))
+                                                      __('Register Failed! Please make sure the RESTful API username/password is correct!')))
                     else:
                         raise ModelQueryException(CLICmdError(__('Refresh Version Failed!')))
-                
+
                 if data.get('type') in OTHER_CATEGORY_LIST:
                     data['version'] = ''
                     data['license_key'] = 'None'
@@ -644,25 +650,25 @@
                 if data.get('type') not in OTHER_CATEGORY_LIST:
                     if not model:
                         raise ModelQueryException(CLICmdError(
-                            __('Register Failed! Invalid model! Only %s are supported.') % ', '.join(DEVICE_STD_LIST)))
+                                                      __('Register Failed! Invalid model! Only %s are supported.') % ', '.join(DEVICE_STD_LIST)))
                     if model != data.get('type'):
                         raise ModelQueryException(CLICmdError(
-                            __('Register Failed! Current device model is %s but you choose %s.') % (model, data['type'])))
+                                                      __('Register Failed! Current device model is %s but you choose %s.') % (model, data['type'])))
 
             db = DB.get_connected_db()
             save_sql = (
-                           "INSERT INTO device("
-                           "id, zone, name, ip_address, protocol, restapi_port, restapi_username, restapi_password, "
-                           "console_username, console_password, connection, status, license_key, gateway_domain, location, "
-                           "firewall_ip, intranet_ip, version, type, own, log_enable, webui_port, device_group, enable_password"
-                           ") Values ('%(id)s', '%(zone)s', '%(name)s', '%(ip)s', '%(protocol)s', '%(restapi_port)s', '%(restapi_username)s', '%(restapi_password)s', '%(console_username)s', '%(console_password)s', 'connected', '%(status)s', '%(license_key)s', '%(gateway_domain)s', '%(location)s', '%(firewall_ip)s', '%(intranet_ip)s', '%(version)s', '%(type)s', '%(own)s', '%(log_enable)d', '%(webui_port)d', '%(device_group)s', '%(enable_password)s')"
-                       ) % data
+                "INSERT INTO device("
+                "id, zone, name, ip_address, protocol, restapi_port, restapi_username, restapi_password, "
+                "console_username, console_password, connection, status, license_key, gateway_domain, location, "
+                "firewall_ip, intranet_ip, version, type, own, log_enable, webui_port, device_group, enable_password"
+                ") Values ('%(id)s', '%(zone)s', '%(name)s', '%(ip)s', '%(protocol)s', '%(restapi_port)s', '%(restapi_username)s', '%(restapi_password)s', '%(console_username)s', '%(console_password)s', 'connected', '%(status)s', '%(license_key)s', '%(gateway_domain)s', '%(location)s', '%(firewall_ip)s', '%(intranet_ip)s', '%(version)s', '%(type)s', '%(own)s', '%(log_enable)d', '%(webui_port)d', '%(device_group)s', '%(enable_password)s')"
+            ) % data
             db.execute_sql(save_sql)
             create_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
             insert_config_sql = (
-                    "INSERT INTO file_list(name, create_time, modify_time, type, comment, device_type) "
-                    "values('%s', '%s', '%s', '%s', '%s', '%s')" % (
-                        data['name'], create_time, create_time, 'device', '', data['type'])
+                "INSERT INTO file_list(name, create_time, modify_time, type, comment, device_type) "
+                "values('%s', '%s', '%s', '%s', '%s', '%s')" % (
+                    data['name'], create_time, create_time, 'device', '', data['type'])
             )
             db.execute_sql(insert_config_sql)
             db.close()
@@ -751,7 +757,7 @@
                     response_data = send_cli_to_device(each, "show snmp", mode='enable')
                     if response_data['message'] != 'success':
                         raise ModelQueryException(CLICmdError(
-                            __('Get device<%s> snmp failed. %s' % (each['ip_address'], response_data['data']))))
+                                                      __('Get device<%s> snmp failed. %s' % (each['ip_address'], response_data['data']))))
                     else:
                         try:
                             result = cli_parse(response_data['data'], [
@@ -809,7 +815,7 @@
                                             for user in rest_body['SNMPGeneral']['v3_user']:
                                                 if 'username' in user and 'auth_password' in user and 'level' in user:
                                                     v3user = user['username'] + ' ' + user['auth_password'] + ' ' + \
-                                                             user['level']
+                                                        user['level']
                                                     if 'priv_password' in user:
                                                         v3user += ' ' + user['priv_password']
                                                     snmp_general['v3user'] = v3user
@@ -822,7 +828,7 @@
                                         db.close()
                                 except Exception as e:
                                     raise ModelQueryException(CLICmdError(
-                                        __('Update device<%s> snmp failed. %s' % (each['ip_address'], str(e)))))
+                                                                  __('Update device<%s> snmp failed. %s' % (each['ip_address'], str(e)))))
                     elif each['type'].lower() in VPN_TYPE_LIST:
                         snmp_general = {}
                         try:
@@ -833,7 +839,7 @@
                                                                          each['restapi_password'])
                         except Exception as e:
                             raise ModelQueryException(CLICmdError(
-                                __('Get device<%s> SNMP version failed. %s' % (each['ip_address'], str(e)))))
+                                                          __('Get device<%s> SNMP version failed. %s' % (each['ip_address'], str(e)))))
                         else:
                             if rest_response_data['status'] == 200:
                                 rest_body = json.loads(rest_response_data['body'])
@@ -843,7 +849,7 @@
                                             snmp_general['snmp_version'] = rest_body['SNMPGeneral']['snmp_version']
                                 except Exception as e:
                                     raise ModelQueryException(CLICmdError(
-                                        __('Set device<%s> snmp version failed. %s' % (each['ip_address'], str(e)))))
+                                                                  __('Set device<%s> snmp version failed. %s' % (each['ip_address'], str(e)))))
 
                         try:
                             new_url = modify_url('/rest/device_type/admintools/snmp/SNMPGeneral/snmp_enable',
@@ -853,7 +859,7 @@
                                                                          each['restapi_password'])
                         except Exception as e:
                             raise ModelQueryException(CLICmdError(
-                                __('Get device<%s> SNMP enable failed. %s' % (each['iip_addressp'], str(e)))))
+                                                          __('Get device<%s> SNMP enable failed. %s' % (each['iip_addressp'], str(e)))))
                         else:
                             if rest_response_data['status'] == 200:
                                 rest_body = json.loads(rest_response_data['body'])
@@ -863,7 +869,7 @@
                                             snmp_general['snmp_enable'] = rest_body['SNMPGeneral']['snmp_enable']
                                 except Exception as e:
                                     raise ModelQueryException(CLICmdError(
-                                        __('Set device<%s> snmp enable failed. %s' % (each['ip_address'], str(e)))))
+                                                                  __('Set device<%s> snmp enable failed. %s' % (each['ip_address'], str(e)))))
 
                         try:
                             new_url = modify_url('/rest/device_type/admintools/snmp/SNMPGeneral/community',
@@ -873,7 +879,7 @@
                                                                          each['restapi_password'])
                         except Exception as e:
                             raise ModelQueryException(CLICmdError(
-                                __('Get device<%s> SNMP community failed. %s' % (each['ip_address'], str(e)))))
+                                                          __('Get device<%s> SNMP community failed. %s' % (each['ip_address'], str(e)))))
                         else:
                             if rest_response_data['status'] == 200:
                                 rest_body = json.loads(rest_response_data['body'])
@@ -883,7 +889,7 @@
                                             snmp_general['community'] = rest_body['SNMPGeneral']['community']
                                 except Exception as e:
                                     raise ModelQueryException(CLICmdError(
-                                        __('Set device<%s> snmp community failed. %s' % (each['ip_address'], str(e)))))
+                                                                  __('Set device<%s> snmp community failed. %s' % (each['ip_address'], str(e)))))
                         try:
                             new_url = modify_url('/rest/device_type/admintools/snmp/SNMPGeneral/v3_user', each['type'])
                             rest_response_data = send_https_rest_request('GET', new_url, '', each['ip_address'],
@@ -901,14 +907,14 @@
                                             for user in rest_body['SNMPGeneral']['v3_user']:
                                                 if 'username' in user and 'auth_password' in user and 'level' in user:
                                                     v3user = user['username'] + ' ' + user['auth_password'] + ' ' + \
-                                                             user['level']
+                                                        user['level']
                                                     if 'priv_password' in user:
                                                         v3user += ' ' + user['priv_password']
                                                     snmp_general['v3user'] = v3user
                                                 break
                                 except Exception as e:
                                     raise ModelQueryException(CLICmdError(
-                                        __('Set device<%s> snmp v3_user failed. %s' % (each['name'], str(e)))))
+                                                                  __('Set device<%s> snmp v3_user failed. %s' % (each['name'], str(e)))))
 
                         db = DB.get_connected_db()
                         update_sql = "UPDATE device SET snmp_general='%s' WHERE id='%s'" % (json.dumps(snmp_general),
@@ -1090,10 +1096,10 @@
                 db.close()
 
             """
-            for item in result:
-                file_path = DEFAULT_CONFIG_FILE_PATH + "backup/" + item[0]
-                shutil.rmtree(file_path.split('.all_cfg_tar')[0])
-                os.remove(file_path)
+for item in result:
+file_path = DEFAULT_CONFIG_FILE_PATH + "backup/" + item[0]
+shutil.rmtree(file_path.split('.all_cfg_tar')[0])
+os.remove(file_path)
             """
             mark_expire_all(get_model('cm', ['configuration', 'config_file', 'ConfigFile']))
             mark_expire_all(get_model('cm', ['configuration', 'vsite_config', 'VsiteConfig']))
@@ -1124,7 +1130,7 @@
                     update_device_connected(item[0]['id'])
                     mark_expire_all(get_model('cm', ['device_mgmt', 'device', 'Device']))
                     raise ModelQueryException(CLICmdError(
-                        __('Timed out! Please check the ip address and make sure the device have already turned on the RESTful API service and the RESTful API port is correct!')))
+                                                  __('Timed out! Please check the ip address and make sure the device have already turned on the RESTful API service and the RESTful API port is correct!')))
                 raise ModelQueryException(CLICmdError(__('Refresh Version Failed!')))
             else:
                 if item[0]['protocol'] == 'xmlrpc':
@@ -1141,7 +1147,7 @@
                         data['version'] = rest_body['SystemInfo']['version']
                     elif rest_response_data['status'] == 401:
                         raise ModelQueryException(CLICmdError(
-                            __('Refresh Failed! Please make sure the RESTful API username/password is correct!')))
+                                                      __('Refresh Failed! Please make sure the RESTful API username/password is correct!')))
                     else:
                         raise ModelQueryException(CLICmdError(__('Refresh Version Failed!')))
 
@@ -1234,7 +1240,7 @@
             device_id_list = [each['id'] for each in pk_list]
             db = DB.get_connected_db()
             fetchall_sql = "SELECT ip_address, protocol, restapi_port, restapi_username, restapi_password, type, enable_password, id FROM device WHERE id = " + "'%s'" % \
-                           device_id_list[0]
+                device_id_list[0]
             data = db.fetchall(fetchall_sql)
             db.close()
             key = ['ip', 'protocol', 'restapi_port', 'restapi_username', 'restapi_password', 'type', 'enable_password',
@@ -1256,7 +1262,7 @@
                         update_device_status(device_id_list[0], 'new', '')
                         mark_expire_all(get_model('cm', ['device_mgmt', 'device', 'Device']))
                         raise ModelQueryException(CLICmdError(
-                            __('This operation is not allowed when the system is running on an AVX appliance.')))
+                                                      __('This operation is not allowed when the system is running on an AVX appliance.')))
                 else:
                     update_device_status(device_id_list[0], 'new', '')
                     mark_expire_all(get_model('cm', ['device_mgmt', 'device', 'Device']))
@@ -1267,11 +1273,11 @@
                 raise ModelQueryException(CLICmdError(__('Internal error.')))
 
         # def send_command_to_device(self, device_info, url, running_params):
-        #     try: 
+        #     try:
         #         rest_response_data = send_https_rest_request('POST', url, running_params, device_info['ip_address'], device_info['restapi_port'], device_info['restapi_username'], device_info['restapi_password'])
         #     except Exception as e:
         #         return 'failed'
-        #     if rest_response_data['status'] == 200: 
+        #     if rest_response_data['status'] == 200:
         #         contents = json.loads(rest_response_data['body'])['contents']
         #         return contents
         #     else:
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/router.py
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/router.py	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/cm/router.py	(working copy)
@@ -1227,17 +1227,20 @@
 def get_task_by_name(request):
     post_data = json.loads(request.POST.get('post_data', None))
     name = post_data['name']
-    config_type = post_data['type']
+    config_type = post_data.get('type', '')
     sql_res2 = []
     db = DB.get_connected_db()
-    fetchall_sql = "SELECT id, name, type, state, next_run_time, description, result_field, device_list, scheduler FROM task WHERE name like '%%%s%%' order by next_run_time DESC;" % (
-        name + "-" if config_type != 'system' else name)
+    
+    search_name = name + "-" if config_type != 'system' else name
+    fetchall_sql = "SELECT id, name, type, state, next_run_time, description, result_field, device_list, scheduler FROM task WHERE name like %s order by next_run_time DESC;"
+    
     if name.endswith(".cfg") or name.endswith(".all_cfg_tar"):
-        name = name[:-4] if name.endswith(".cfg") else name[:-12]
-        fetchall_sql2 = "SELECT id, name, type, state, next_run_time, description, result_field, device_list, scheduler FROM task WHERE name like '%%%s%%' and type = 'config_check' order by next_run_time DESC;" % (
-                name + "-")
-        sql_res2 = db.fetchall(fetchall_sql2)
-    sql_res = db.fetchall(fetchall_sql)
+        name_prefix = name[:-4] if name.endswith(".cfg") else name[:-12]
+        search_name_2 = name_prefix + "-"
+        fetchall_sql2 = "SELECT id, name, type, state, next_run_time, description, result_field, device_list, scheduler FROM task WHERE name like %s and type = 'config_check' order by next_run_time DESC;"
+        sql_res2 = db.fetchall(fetchall_sql2, ('%' + search_name_2 + '%',))
+        
+    sql_res = db.fetchall(fetchall_sql, ('%' + search_name + '%',))
     db.close()
     key = ['id', 'name', 'type', 'state', 'next_run_time', 'description', 'result_field', 'device_list', 'scheduler']
     result = [dict(zip(key, each)) for each in sql_res]
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/config-hub/config-hub.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/config-hub/config-hub.scss	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/config-hub/config-hub.scss	(working copy)
@@ -0,0 +1,20 @@
+// Custom Styling for Config Hub if needed beyond TabContainer defaults
+:host {
+    display: block;
+    height: 100%;
+}
+
+::ng-deep app-tab-container {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+
+    .mat-mdc-tab-group {
+        flex: 1;
+        overflow: hidden;
+    }
+
+    .mat-mdc-tab-body-wrapper {
+        height: 100%;
+    }
+}
\ No newline at end of file
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/config-hub/config-hub.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/config-hub/config-hub.ts	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/config-hub/config-hub.ts	(working copy)
@@ -1,14 +1,15 @@
-import {Component} from '@angular/core';
-import {SharedModule} from '../../shared/shared-module';
+import { Component } from '@angular/core';
+import { SharedModule } from '../../shared/shared-module';
 import {
   DeviceCustomConfigOverview
 } from '../sub-components/device-custom-config-overview/device-custom-config-overview';
-import {DeviceClonedFiles} from '../sub-components/device-cloned-files/device-cloned-files';
-import {DeviceConfigOverview} from '../sub-components/device-config-overview/device-config-overview';
+import { DeviceClonedFiles } from '../sub-components/device-cloned-files/device-cloned-files';
+import { DeviceConfigOverview } from '../sub-components/device-config-overview/device-config-overview';
 import {
   DeviceCustomConfigTemplates
 } from '../sub-components/device-custom-config-templates/device-custom-config-templates';
-import {TabContainer, TabDefinition} from '../common/tab-container/tab-container';
+import { TabContainer, TabDefinition } from '../common/tab-container/tab-container';
+import { faCopy, faFileCode, faFileLines, faSliders } from '@fortawesome/free-solid-svg-icons';
 
 @Component({
   selector: 'app-config-hub',
@@ -19,9 +20,9 @@
 export class ConfigHub {
 
   tabDefinitions: TabDefinition[] = [
-    {label: 'Device Configuration Files', component: DeviceCustomConfigOverview, paramName: 'device-config'},
-    {label: 'Cloned Files', component: DeviceClonedFiles, paramName: 'cloned-files'},
-    {label: 'Custom Configuration', component: DeviceConfigOverview, paramName: 'custom-config'},
-    {label: 'Custom Templates', component: DeviceCustomConfigTemplates, paramName: 'custom-templates'},
+    { label: 'Device Configuration Files', component: DeviceConfigOverview, paramName: 'device-config', icon: faFileCode },
+    { label: 'Cloned Files', component: DeviceClonedFiles, paramName: 'cloned-files', icon: faCopy },
+    { label: 'Custom Configuration', component: DeviceCustomConfigOverview, paramName: 'custom-config', icon: faSliders },
+    { label: 'Custom Templates', component: DeviceCustomConfigTemplates, paramName: 'custom-templates', icon: faFileLines },
   ];
 }
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 2820)
+++ /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)
@@ -12,14 +12,14 @@
   <mat-card-header>
     <mat-card-title>Historical Backups</mat-card-title>
     <div>
-      <button mat-raised-button (click)="createDeviceConfigBackup()"
-              matTooltip="Backup device configuration">Create Backup
+      <button mat-raised-button (click)="createDeviceConfigBackup()" matTooltip="Backup device configuration">Create
+        Backup
       </button>
     </div>
   </mat-card-header>
 </mat-card>
 <div class="table-container">
-  <table mat-table [dataSource]="dataSource" class="mat-elevation-z1">
+  <table mat-table [dataSource]="dataSource" class="mat-elevation-z1 modern-table">
     <ng-container matColumnDef="serial">
       <th mat-header-cell *matHeaderCellDef> No.</th>
       <td mat-cell *matCellDef="let element; let i = index;"> {{ i | globalSerial }}</td>
@@ -45,13 +45,13 @@
       <td mat-cell *matCellDef="let element">
         <div class="row-action a-link">
           <fa-icon [icon]="['far', 'clone']" size="lg" matTooltip="Clone"
-                   (click)="cloneDeviceBackupConfig(element)"></fa-icon>
+            (click)="cloneDeviceBackupConfig(element)"></fa-icon>
           <fa-icon [icon]="['far', 'window-restore']" size="lg" matTooltip="Recover"
-                   (click)="recoverDeviceBackupConfig(element)"></fa-icon>
+            (click)="recoverDeviceBackupConfig(element)"></fa-icon>
           <fa-icon [icon]="['fas', 'list-check']" size="lg" matTooltip="Show Task"
-                   (click)="showConfigTask(element)"></fa-icon>
+            (click)="showConfigTask(element)"></fa-icon>
           <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete Backup"
-                   (click)="deleteDeviceBackupConfig(element)"></fa-icon>
+            (click)="deleteDeviceBackupConfig(element)"></fa-icon>
         </div>
       </td>
     </ng-container>
@@ -61,9 +61,5 @@
       <td class="mat-cell" colspan="11">No results found.</td>
     </tr>
   </table>
-  <mat-paginator
-    [pageSizeOptions]="[10, 15, 20, 25]"
-    [length]="totalRecords"
-    showFirstLastButtons
-  ></mat-paginator>
-</div>
+  <mat-paginator [pageSizeOptions]="[10, 15, 20, 25]" [length]="totalRecords" showFirstLastButtons></mat-paginator>
+</div>
\ No newline at end of file
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.scss	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-backup-files/device-backup-files.scss	(working copy)
@@ -0,0 +1,90 @@
+table.modern-table {
+    width: 100%;
+
+    th.mat-header-cell {
+        background-color: #f8f9fa;
+        color: #5f6368;
+        font-weight: 600;
+        font-size: 13px;
+        text-transform: uppercase;
+        padding: 0 16px;
+        height: 48px;
+        border-bottom: 1px solid #e0e0e0;
+    }
+
+    td.mat-cell {
+        padding: 0 16px;
+        font-size: 14px;
+        color: #3c4043;
+        height: 48px;
+        border-bottom: 1px solid #f1f3f4;
+    }
+
+    tr.mat-row:hover {
+        background-color: #f8f9fa;
+    }
+
+    .row-link {
+        color: #1967d2;
+        text-decoration: none;
+        cursor: pointer;
+        font-weight: 500;
+
+        &:hover {
+            text-decoration: underline;
+        }
+    }
+
+    .secondary-text {
+        color: #5f6368;
+    }
+
+    .row-action {
+        display: flex;
+        gap: 8px;
+        align-items: center;
+
+        button {
+            width: 32px;
+            height: 32px;
+            line-height: 32px;
+
+            fa-icon {
+                font-size: 14px;
+                color: #5f6368;
+            }
+
+            &:hover fa-icon {
+                color: #1967d2;
+            }
+
+            &[color="warn"]:hover fa-icon {
+                color: #d32f2f;
+            }
+        }
+    }
+
+    /* No Data Row */
+    .no-data-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 48px 0;
+        color: #757575;
+        gap: 12px;
+
+        fa-icon {
+            font-size: 40px;
+            opacity: 0.5;
+        }
+
+        span {
+            font-size: 14px;
+        }
+    }
+}
+
+.table-container {
+    padding: 16px;
+}
\ No newline at end of file
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 2820)
+++ /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)
@@ -178,8 +178,8 @@
     this._confirmation.openConfirmDialog({
       title: `Delete Device Configuration File?`,
       message: confirmMsg,
-      confirmButtonText: 'Yes, Delete It',
-      cancelButtonText: 'No, Keep It',
+      confirmButtonText: 'Delete',
+      cancelButtonText: 'Cancel',
       confirmButtonColor: 'warn',
       cancelButtonColor: 'primary'
     }).subscribe((result: boolean) => {
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 2820)
+++ /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)
@@ -29,18 +29,11 @@
         <td class="mat-cell" colspan="11">No results found.</td>
       </tr>
     </table>
-    <mat-paginator
-      [pageSizeOptions]="[10, 15, 20, 25]"
-      [length]="totalRecords"
-      showFirstLastButtons
-    ></mat-paginator>
+    <mat-paginator [pageSizeOptions]="[10, 15, 20, 25]" [length]="totalRecords" showFirstLastButtons></mat-paginator>
   </div>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button
-    mat-button
-    color="basic"
-    (click)="onCancel()">
-    Cancel
+  <button mat-button color="basic" (click)="onCancel()">
+    Close
   </button>
-</mat-dialog-actions>
+</mat-dialog-actions>
\ No newline at end of file
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 2820)
+++ /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)
@@ -1,61 +1,80 @@
-<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="deviceName">
-      <th mat-header-cell *matHeaderCellDef>Configuration Filename</th>
-      <td mat-cell *matCellDef="let element">
-        <a class="details-page-link" (click)="editDeviceConfiguration(element)">{{ element.name }}</a>
-      </td>
-    </ng-container>
-    <ng-container matColumnDef="fileType">
-      <th mat-header-cell *matHeaderCellDef>File Type</th>
-      <td mat-cell *matCellDef="let element"> {{ element.file_type }}</td>
-    </ng-container>
-    <ng-container matColumnDef="deviceType">
-      <th mat-header-cell *matHeaderCellDef>Device Type</th>
-      <td mat-cell *matCellDef="let element"> {{ element.device_type }}</td>
-    </ng-container>
-    <ng-container matColumnDef="createTime">
-      <th mat-header-cell *matHeaderCellDef>Create Time</th>
-      <td mat-cell *matCellDef="let element">{{ element.create_time }}</td>
-    </ng-container>
-    <ng-container matColumnDef="cloneSource">
-      <th mat-header-cell *matHeaderCellDef>Clone Source</th>
-      <td mat-cell *matCellDef="let element">{{ element.modify_time }}</td>
-    </ng-container>
-    <ng-container matColumnDef="comment">
-      <th mat-header-cell *matHeaderCellDef>Comment</th>
-      <td mat-cell *matCellDef="let element">{{ element.comment }}</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', 'clone']" size="lg" matTooltip="Clone configuration"
-                   (click)="cloneConfiguration(element)"></fa-icon>
-          <fa-icon [icon]="['fas', 'code-compare']" size="lg" matTooltip="Compare configuration"
-                   (click)="compareConfiguration(element)"></fa-icon>
-          <fa-icon [icon]="['fas', 'gears']" size="lg" matTooltip="Apply configuration"
-                   (click)="applyConfiguration(element)"></fa-icon>
-          <fa-icon [icon]="['fas', 'list-check']" size="lg" matTooltip="Task for this configuration"
-                   (click)="showTaskConfiguration(element)"></fa-icon>
-          <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete configuration"
-                   (click)="deleteConfiguration(element)"></fa-icon>
-        </div>
-      </td>
-    </ng-container>
-    <tr mat-header-row *matHeaderRowDef="deviceColumns"></tr>
-    <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
-    <tr class="mat-row table-no-data" *matNoDataRow>
-      <td class="mat-cell" colspan="11">No results found.</td>
-    </tr>
-  </table>
-  <mat-paginator
-    [pageSizeOptions]="[10, 15, 20, 25]"
-    [length]="totalRecords"
-    showFirstLastButtons
-  ></mat-paginator>
-</div>
+<div class="page-container">
+  <mat-card class="table-card appearance-outlined">
+    <mat-card-header>
+      <mat-card-title>Cloned Configuration Files</mat-card-title>
+    </mat-card-header>
+    <mat-card-content>
+      <div class="table-wrapper">
+        <table mat-table [dataSource]="dataSource" class="modern-table">
+          <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="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Configuration Filename</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="row-link" (click)="editDeviceConfiguration(element)">{{ element.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="fileType">
+            <th mat-header-cell *matHeaderCellDef>File Type</th>
+            <td mat-cell *matCellDef="let element">
+              <span class="badge" [ngClass]="element.file_type">{{ element.file_type }}</span>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceType">
+            <th mat-header-cell *matHeaderCellDef>Device Type</th>
+            <td mat-cell *matCellDef="let element"> {{ element.device_type }}</td>
+          </ng-container>
+          <ng-container matColumnDef="createTime">
+            <th mat-header-cell *matHeaderCellDef>Create Time</th>
+            <td mat-cell *matCellDef="let element" class="secondary-text">{{ element.create_time }}</td>
+          </ng-container>
+          <ng-container matColumnDef="cloneSource">
+            <th mat-header-cell *matHeaderCellDef>Clone Source</th>
+            <td mat-cell *matCellDef="let element" class="secondary-text">{{ element.modify_time }}</td>
+          </ng-container>
+          <ng-container matColumnDef="comment">
+            <th mat-header-cell *matHeaderCellDef>Comment</th>
+            <td mat-cell *matCellDef="let element" class="secondary-text">{{ element.comment }}</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">
+                <button mat-icon-button matTooltip="Clone configuration" (click)="cloneConfiguration(element)">
+                  <fa-icon [icon]="['far', 'clone']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Compare configuration" (click)="compareConfiguration(element)">
+                  <fa-icon [icon]="['fas', 'code-compare']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Apply configuration" (click)="applyConfiguration(element)">
+                  <fa-icon [icon]="['fas', 'gears']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Task for this configuration"
+                  (click)="showTaskConfiguration(element)">
+                  <fa-icon [icon]="['fas', 'list-check']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button color="warn" matTooltip="Delete configuration"
+                  (click)="deleteConfiguration(element)">
+                  <fa-icon [icon]="['far', 'trash-can']" size="lg"></fa-icon>
+                </button>
+              </div>
+            </td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="deviceColumns; sticky: true"></tr>
+          <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="8">
+              <div class="no-data-content">
+                <fa-icon [icon]="['far', 'folder-open']"></fa-icon>
+                <span>No cloned files found</span>
+              </div>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <mat-paginator [pageSizeOptions]="[10, 15, 20, 25]" [length]="totalRecords" showFirstLastButtons></mat-paginator>
+    </mat-card-content>
+  </mat-card>
+</div>
\ No newline at end of file
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.scss	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/device-cloned-files.scss	(working copy)
@@ -0,0 +1,148 @@
+.page-container {
+    padding: 16px;
+    display: flex;
+    flex-direction: column;
+    box-sizing: border-box;
+}
+
+mat-card.table-card {
+    display: flex;
+    flex-direction: column;
+    border-radius: 8px;
+    background: #fff;
+    border: none;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+
+    &.appearance-outlined {
+        border: 1px solid #e0e0e0;
+        box-shadow: none;
+    }
+
+    mat-card-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 0 16px;
+        height: 60px;
+        max-height: 60px;
+        border-bottom: 1px solid #f0f0f0;
+        box-sizing: border-box;
+
+        mat-card-title {
+            font-size: 18px;
+            font-weight: 500;
+            margin: 0;
+        }
+    }
+
+    mat-card-content {
+        display: flex;
+        flex-direction: column;
+        padding: 0;
+
+        .table-wrapper {
+            overflow: auto;
+        }
+    }
+}
+
+table.modern-table {
+    width: 100%;
+
+    th.mat-header-cell {
+        background-color: #f8f9fa;
+        color: #5f6368;
+        font-weight: 600;
+        font-size: 13px;
+        text-transform: uppercase;
+        padding: 0 16px;
+        height: 48px;
+        border-bottom: 1px solid #e0e0e0;
+    }
+
+    td.mat-cell {
+        padding: 0 16px;
+        font-size: 14px;
+        color: #3c4043;
+        height: 48px;
+        border-bottom: 1px solid #f1f3f4;
+    }
+
+    tr.mat-row:hover {
+        background-color: #f8f9fa;
+    }
+
+    .row-link {
+        color: #1967d2;
+        text-decoration: none;
+        cursor: pointer;
+        font-weight: 500;
+
+        &:hover {
+            text-decoration: underline;
+        }
+    }
+
+    .secondary-text {
+        color: #5f6368;
+    }
+
+    .badge {
+        padding: 2px 8px;
+        border-radius: 4px;
+        font-size: 12px;
+        font-weight: 500;
+        background-color: #e8f0fe;
+        color: #1a73e8;
+
+        &.template {
+            background-color: #e6f4ea;
+            color: #137333;
+        }
+    }
+
+    .row-action {
+        display: flex;
+        gap: 8px;
+        align-items: center;
+
+        button {
+            width: 32px;
+            height: 32px;
+            line-height: 32px;
+
+            fa-icon {
+                font-size: 14px;
+                color: #5f6368;
+            }
+
+            &:hover fa-icon {
+                color: #1967d2;
+            }
+
+            &[color="warn"]:hover fa-icon {
+                color: #d32f2f;
+            }
+        }
+    }
+
+    /* No Data Row */
+    .no-data-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 48px 0;
+        color: #757575;
+        gap: 12px;
+
+        fa-icon {
+            font-size: 40px;
+            opacity: 0.5;
+        }
+
+        span {
+            font-size: 14px;
+        }
+    }
+}
\ No newline at end of file
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 2820)
+++ /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)
@@ -1,16 +1,16 @@
-import {AfterViewInit, ChangeDetectorRef, Component, inject, OnDestroy, OnInit, ViewChild} from '@angular/core';
-import {SharedModule} from '../../../shared/shared-module';
-import {NotificationService} from '../../../services/notification';
-import {DeviceService} from '../../../services/device-service';
-import {MatTableDataSource} from '@angular/material/table';
-import {MatPaginator} from '@angular/material/paginator';
-import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog';
-import {take} from 'rxjs/operators';
-import {Confirmation} from '../../../services/confirmation';
-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';
+import { AfterViewInit, ChangeDetectorRef, Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { SharedModule } from '../../../shared/shared-module';
+import { NotificationService } from '../../../services/notification';
+import { DeviceService } from '../../../services/device-service';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog';
+import { take } from 'rxjs/operators';
+import { Confirmation } from '../../../services/confirmation';
+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',
@@ -76,7 +76,7 @@
 
   groupDevicesByType(): void {
     this.groupedDevices = this.devices.reduce((acc: any, device: any) => {
-      const type = device.type;
+      const type = device?.type ? device.type.toLowerCase() : 'unknown';
       if (!acc[type]) {
         acc[type] = [];
       }
@@ -132,10 +132,13 @@
   }
 
   editDeviceConfiguration(_device: any) {
-    this.dialogConfig.data = {
+    const dialogConfig = new MatDialogConfig();
+    dialogConfig.width = '60%';
+    dialogConfig.minWidth = '600px';
+    dialogConfig.data = {
       config: _device,
     };
-    const dialogRef = this.dialog.open(EditConfigurationDialog, this.dialogConfig);
+    const dialogRef = this.dialog.open(EditConfigurationDialog, dialogConfig);
     dialogRef.afterClosed().subscribe(() => {
     })
   }
@@ -153,7 +156,7 @@
     this.dialogConfig.width = '60%';
     this.dialogConfig.data = {
       device: _device,
-      devices: this.groupedDevices[_device?.device_type],
+      devices: this.groupedDevices[_device?.device_type?.toLowerCase()],
     }
     const dialogRef = this.dialog.open(CompareCloneConfigDialog, this.dialogConfig);
     dialogRef.afterClosed().subscribe((result: boolean) => {
@@ -164,7 +167,7 @@
     this.dialogConfig.width = '60%';
     this.dialogConfig.data = {
       device: _device,
-      devices: this.groupedDevices[_device?.device_type],
+      devices: this.groupedDevices[_device?.device_type?.toLowerCase()],
       groups: this.groups
     }
     const dialogRef = this.dialog.open(ApplyConfigurationDialog, this.dialogConfig);
@@ -186,8 +189,8 @@
     this._confirmation.openConfirmDialog({
       title: `Delete Configuration File?`,
       message: confirmMsg,
-      confirmButtonText: 'Yes, Delete It',
-      cancelButtonText: 'No, Keep It',
+      confirmButtonText: 'Delete',
+      cancelButtonText: 'Cancel',
       confirmButtonColor: 'warn',
       cancelButtonColor: 'primary'
     }).subscribe((result: boolean) => {
@@ -233,15 +236,15 @@
   configForm: FormGroup;
 
   configOptions: any = [
-    {value: 'immediate', label: 'Immediate'},
-    {value: 'deferred', label: 'Deferred'},
-    {value: 'loop', label: 'Loop'},
+    { value: 'immediate', label: 'Immediate' },
+    { value: 'deferred', label: 'Deferred' },
+    { value: 'loop', label: 'Loop' },
   ]
 
   intervalUnits: any = [
-    {value: 1, label: 'Hour'},
-    {value: 24, label: 'Day'},
-    {value: 168, label: 'Week'},
+    { value: 1, label: 'Hour' },
+    { value: 24, label: 'Day' },
+    { value: 168, label: 'Week' },
   ]
 
   constructor(
@@ -303,18 +306,18 @@
 
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Device config check initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Device config check initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel(): void {
@@ -372,8 +375,8 @@
   readonly dialogRef = inject(MatDialogRef<ApplyConfigurationDialog>);
   configForm: FormGroup;
   configOptions: any = [
-    {value: 'immediate', label: 'Immediate'},
-    {value: 'deferred', label: 'Deferred'},
+    { value: 'immediate', label: 'Immediate' },
+    { value: 'deferred', label: 'Deferred' },
   ]
   private subscriptions: Subscription = new Subscription();
 
@@ -464,18 +467,18 @@
     payload.set('options', JSON.stringify(rawPayload));
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Apply configuration initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Apply configuration initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   ngOnDestroy(): void {
@@ -490,7 +493,37 @@
 @Component({
   selector: 'edit-configuration',
   templateUrl: './edit-configuration.html',
-  imports: [SharedModule]
+  imports: [SharedModule],
+  styles: [`
+    mat-dialog-content {
+      max-height: 80vh;
+      width: 100%;
+      display: flex;
+      flex-direction: column;
+      overflow-x: hidden; /* Prevent horizontal scroll */
+    }
+    form {
+      display: flex;
+      flex-direction: column;
+      flex: 1;
+      height: 100%;
+    }
+    .form-field-wrapper {
+      display: flex;
+      flex-direction: column; 
+      flex: 1;
+    }
+    textarea {
+      flex: 1;
+      min-height: 200px;
+      resize: vertical;
+      width: 100%;
+      box-sizing: border-box;
+      border: 1px solid #ccc; /* Add border for visibility if not using mat-form-field */
+      border-radius: 4px; /* Soften edges */
+      padding: 8px;
+    }
+  `]
 })
 export class EditConfigurationDialog implements OnInit, OnDestroy {
 
@@ -500,8 +533,8 @@
   deviceType: any = '';
   aGOptions: any = [];
   configOptions: any = [
-    {value: 'immediate', label: 'Immediate'},
-    {value: 'deferred', label: 'Deferred'},
+    { value: 'immediate', label: 'Immediate' },
+    { value: 'deferred', label: 'Deferred' },
   ]
   private subscriptions: Subscription = new Subscription();
 
@@ -562,7 +595,7 @@
   getAGConfigAssociatedVsites() {
     this.aGOptions = []
     let payload = new FormData();
-    payload.set('initial_filter', JSON.stringify({name: this.data?.config?.name.split('.')[0]}));
+    payload.set('initial_filter', JSON.stringify({ name: this.data?.config?.name.split('.')[0] }));
     this._device.getAGConfigAssociatedVsites(payload)
       .pipe(take(1))
       .subscribe({
@@ -621,33 +654,33 @@
       filename = filename.split('.')[0];
       this._device.updateAGVSiteConfig(filename, this.configForm.value.aGOption, payload)
         .pipe(take(1)).subscribe({
-        next: (result: any) => {
-          if (result) {
-            this._notification.showSuccess(`The configuration has been updated successfully.`);
-            this.dialogRef.close(true);
+          next: (result: any) => {
+            if (result) {
+              this._notification.showSuccess(`The configuration has been updated successfully.`);
+              this.dialogRef.close(true);
+            }
+            this._cdRef.detectChanges();
+          },
+          error: error => {
+            this._notification.showError(`Error: ${error?.message}`);
+            this._cdRef.detectChanges();
           }
-          this._cdRef.detectChanges();
-        },
-        error: error => {
-          this._notification.showError(`Error: ${error?.message}`);
-          this._cdRef.detectChanges();
-        }
-      })
+        })
     } else {
       this._device.updateDeviceConfigByConfigFileName(filename, this.data?.config?.file_type, payload)
         .pipe(take(1)).subscribe({
-        next: (result: any) => {
-          if (result) {
-            this._notification.showSuccess(`The configuration has been updated successfully.`);
-            this.dialogRef.close(true);
+          next: (result: any) => {
+            if (result) {
+              this._notification.showSuccess(`The configuration has been updated successfully.`);
+              this.dialogRef.close(true);
+            }
+            this._cdRef.detectChanges();
+          },
+          error: error => {
+            this._notification.showError(`Error: ${error?.message}`);
+            this._cdRef.detectChanges();
           }
-          this._cdRef.detectChanges();
-        },
-        error: error => {
-          this._notification.showError(`Error: ${error?.message}`);
-          this._cdRef.detectChanges();
-        }
-      })
+        })
     }
   }
 
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/edit-configuration.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/edit-configuration.html	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-cloned-files/edit-configuration.html	(working copy)
@@ -1,56 +1,48 @@
 <h2 mat-dialog-title>Edit Configuration</h2>
 <mat-dialog-content>
-  <form
-    (ngSubmit)="onSubmit()"
-    [formGroup]="configForm"
-  >
-    @if ((deviceType === 'ag' || deviceType === 'vxag') && this.data?.config?.file_type !== 'customize' && this.data?.config?.file_type !== 'template') {
-      <div class="form-field-wrapper">
-        <label for="aGOption" class="form-label">Select Virtual Site *</label>
-        <mat-form-field appearance="outline" subscriptSizing="dynamic">
-          <mat-select formControlName="aGOption" (selectionChange)="onSelectionChange()">
-            <mat-option value="global">global</mat-option>
-            @for (_option of aGOptions; track _option) {
-              <mat-option [value]="_option.vsite_name">{{ _option.vsite_name }}</mat-option>
-            }
-          </mat-select>
-          @if (configForm.get('aGOption')?.invalid && configForm.get('aGOption')?.touched) {
-            <mat-error>
-              @if (configForm.get('aGOption')?.errors?.['required']) {
-                Virtual site is required.
-              } @else {
-                Invalid virtual site format.
-              }
-            </mat-error>
-          }
-        </mat-form-field>
-      </div>
-    }
+  <form (ngSubmit)="onSubmit()" [formGroup]="configForm">
+    @if ((deviceType === 'ag' || deviceType === 'vxag') && this.data?.config?.file_type !== 'customize' &&
+    this.data?.config?.file_type !== 'template') {
     <div class="form-field-wrapper">
-      <textarea matInput formControlName="device_config" cols="80" rows="45"></textarea>
-      @if (configForm.get('device_config')?.invalid && configForm.get('device_config')?.touched) {
+      <label for="aGOption" class="form-label">Select Virtual Site *</label>
+      <mat-form-field appearance="outline" subscriptSizing="dynamic">
+        <mat-select formControlName="aGOption" (selectionChange)="onSelectionChange()">
+          <mat-option value="global">global</mat-option>
+          @for (_option of aGOptions; track _option) {
+          <mat-option [value]="_option.vsite_name">{{ _option.vsite_name }}</mat-option>
+          }
+        </mat-select>
+        @if (configForm.get('aGOption')?.invalid && configForm.get('aGOption')?.touched) {
         <mat-error>
-          @if (configForm.get('device_config')?.errors?.['required']) {
-            Device configuration is required.
+          @if (configForm.get('aGOption')?.errors?.['required']) {
+          Virtual site is required.
           } @else {
-            Invalid device configuration format.
+          Invalid virtual site format.
           }
         </mat-error>
+        }
+      </mat-form-field>
+    </div>
+    }
+    <div class="form-field-wrapper">
+      <textarea matInput formControlName="device_config"></textarea>
+      @if (configForm.get('device_config')?.invalid && configForm.get('device_config')?.touched) {
+      <mat-error>
+        @if (configForm.get('device_config')?.errors?.['required']) {
+        Device configuration is required.
+        } @else {
+        Invalid device configuration format.
+        }
+      </mat-error>
       }
     </div>
   </form>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button
-    mat-button
-    color="basic"
-    (click)="onCancel()">
+  <button mat-button color="basic" (click)="onCancel()">
     Cancel
   </button>
-  <button
-    mat-raised-button
-    color="primary"
-    (click)="onSubmit()">
+  <button mat-raised-button color="primary" (click)="onSubmit()">
     Submit
   </button>
-</mat-dialog-actions>
+</mat-dialog-actions>
\ No newline at end of file
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 2820)
+++ /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)
@@ -1,83 +1,95 @@
-<mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <div>
-      <button mat-raised-button (click)="compareConfig()">
-        <fa-icon [icon]="['fas', 'code-compare']"></fa-icon>
-        Configuration Comparison
-      </button>&nbsp;&nbsp;
-      <button mat-raised-button (click)="scheduleBackupConfig()">
-        <fa-icon [icon]="['far', 'clock']"></fa-icon>
-        Schedule Backup
-      </button>&nbsp;&nbsp;
-      <button mat-raised-button (click)="compareBackupConfigVersion()">
-        <fa-icon [icon]="['fas', 'code-compare']"></fa-icon>
-        Backup Version Compare
-      </button>&nbsp;&nbsp;
-      <button mat-raised-button (click)="backupConfig()">
-        <fa-icon [icon]="['far', 'copy']"></fa-icon>
-        Backup
-      </button>
-    </div>
-  </mat-card-header>
-</mat-card>
-<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="deviceName">
-      <th mat-header-cell *matHeaderCellDef>Device Name</th>
-      <td mat-cell *matCellDef="let element">
-        <a class="details-page-link" (click)="viewDeviceConfiguration(element)">{{ element.name }}</a>
-      </td>
-    </ng-container>
-    <ng-container matColumnDef="deviceType">
-      <th mat-header-cell *matHeaderCellDef>Device Type</th>
-      <td mat-cell *matCellDef="let element"> {{ element.device_type }}</td>
-    </ng-container>
-    <ng-container matColumnDef="lastBackupTime">
-      <th mat-header-cell *matHeaderCellDef>Last Backup Time</th>
-      <td mat-cell *matCellDef="let element">{{ element.lastBackupTime }}</td>
-    </ng-container>
-    <ng-container matColumnDef="status">
-      <th mat-header-cell *matHeaderCellDef> Status</th>
-      <td mat-cell *matCellDef="let element">
-        <div class="row-action a-link">
-          @if (element?.status === 'enabled') {
-            <fa-icon [icon]="['far', 'check-circle']" class="success-icon"></fa-icon>
-          } @else {
-            <fa-icon [icon]="['far', 'xmark-circle']" class="delete-icon"></fa-icon>
-          }
-        </div>
-      </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]="['fas', 'timeline']" size="lg" matTooltip="View historical backup files"
-                   (click)="viewDeviceConfigFilesHistory(element)"></fa-icon>
-          <fa-icon [icon]="['fas', 'code-compare']" size="lg" matTooltip="Compare with last backup file"
-                   (click)="compareDeviceConfigLastBackup(element)"></fa-icon>
-          <fa-icon [icon]="['far', 'clone']" size="lg" matTooltip="Clone configuration"
-                   (click)="cloneDeviceConfig(element)"></fa-icon>
-          <fa-icon [icon]="['fas', 'list-check']" size="lg" matTooltip="Task for this configuration"
-                   (click)="showDeviceConfigTask(element)"></fa-icon>
-          <fa-icon [icon]="['far', 'copy']" size="lg" matTooltip="Backup device configuration"
-                   (click)="backupDeviceConfig(element)"></fa-icon>
-        </div>
-      </td>
-    </ng-container>
-    <tr mat-header-row *matHeaderRowDef="deviceColumns"></tr>
-    <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
-    <tr class="mat-row table-no-data" *matNoDataRow>
-      <td class="mat-cell" colspan="11">No results found.</td>
-    </tr>
-  </table>
-  <mat-paginator
-    [pageSizeOptions]="[10, 15, 20, 25]"
-    [length]="totalRecords"
-    showFirstLastButtons
-  ></mat-paginator>
-</div>
+<div class="page-container">
+  <mat-card class="table-card appearance-outlined">
+    <mat-card-header>
+      <mat-card-title>Device Configuration Files</mat-card-title>
+      <div class="header-actions">
+        <button mat-button (click)="compareConfig()">
+          <fa-icon [icon]="['fas', 'code-compare']"></fa-icon> Comparison
+        </button>
+        <button mat-button (click)="scheduleBackupConfig()">
+          <fa-icon [icon]="['far', 'clock']"></fa-icon> Schedule
+        </button>
+        <button mat-button (click)="compareBackupConfigVersion()">
+          <fa-icon [icon]="['fas', 'code-compare']"></fa-icon> Version Compare
+        </button>
+        <button mat-flat-button color="primary" (click)="backupConfig()">
+          <fa-icon [icon]="['far', 'copy']"></fa-icon> Backup
+        </button>
+      </div>
+    </mat-card-header>
+    <mat-card-content>
+      <div class="table-wrapper">
+        <table mat-table [dataSource]="dataSource" class="modern-table">
+          <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="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Device Name</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="row-link" (click)="viewDeviceConfiguration(element)">{{ element.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceType">
+            <th mat-header-cell *matHeaderCellDef>Device Type</th>
+            <td mat-cell *matCellDef="let element"> {{ element.device_type }}</td>
+          </ng-container>
+          <ng-container matColumnDef="lastBackupTime">
+            <th mat-header-cell *matHeaderCellDef>Last Backup Time</th>
+            <td mat-cell *matCellDef="let element" class="secondary-text">{{ element.lastBackupTime }}</td>
+          </ng-container>
+          <ng-container matColumnDef="status">
+            <th mat-header-cell *matHeaderCellDef> Status</th>
+            <td mat-cell *matCellDef="let element">
+              <div class="status-cell">
+                @if (element?.status === 'enabled') {
+                <fa-icon [icon]="['far', 'check-circle']" class="success-icon"></fa-icon>
+                <span class="status-text success">Enabled</span>
+                } @else {
+                <fa-icon [icon]="['far', 'xmark-circle']" class="error-icon"></fa-icon>
+                <span class="status-text error">Disabled</span>
+                }
+              </div>
+            </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">
+                <button mat-icon-button matTooltip="View historical backup files"
+                  (click)="viewDeviceConfigFilesHistory(element)">
+                  <fa-icon [icon]="['fas', 'timeline']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Compare with last backup file"
+                  (click)="compareDeviceConfigLastBackup(element)">
+                  <fa-icon [icon]="['fas', 'code-compare']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Clone configuration" (click)="cloneDeviceConfig(element)">
+                  <fa-icon [icon]="['far', 'clone']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Task for this configuration"
+                  (click)="showDeviceConfigTask(element)">
+                  <fa-icon [icon]="['fas', 'list-check']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Backup device configuration" (click)="backupDeviceConfig(element)">
+                  <fa-icon [icon]="['far', 'copy']" size="lg"></fa-icon>
+                </button>
+              </div>
+            </td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="deviceColumns; sticky: true"></tr>
+          <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="11">
+              <div class="no-data-content">
+                <fa-icon [icon]="['far', 'folder-open']"></fa-icon>
+                <span>No device configurations found</span>
+              </div>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <mat-paginator [pageSizeOptions]="[10, 15, 20, 25]" [length]="totalRecords" showFirstLastButtons></mat-paginator>
+    </mat-card-content>
+  </mat-card>
+</div>
\ No newline at end of file
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.scss	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/device-config-overview.scss	(working copy)
@@ -0,0 +1,178 @@
+.page-container {
+    padding: 16px;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    box-sizing: border-box;
+}
+
+mat-card.table-card {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+    overflow: hidden;
+    border-radius: 8px;
+    background: #fff;
+    border: none;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+
+    &.appearance-outlined {
+        border: 1px solid #e0e0e0;
+        box-shadow: none;
+    }
+
+    mat-card-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 16px;
+        border-bottom: 1px solid #f0f0f0;
+
+        mat-card-title {
+            font-size: 18px;
+            font-weight: 500;
+            margin: 0;
+        }
+
+        .header-actions {
+            display: flex;
+            gap: 8px;
+
+            button {
+                display: flex;
+                align-items: center;
+                gap: 8px;
+
+                fa-icon {
+                    font-size: 14px;
+                }
+            }
+        }
+    }
+
+    mat-card-content {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        padding: 0;
+        overflow: hidden;
+
+        .table-wrapper {
+            flex: 1;
+            overflow: auto;
+        }
+    }
+}
+
+table.modern-table {
+    width: 100%;
+
+    th.mat-header-cell {
+        background-color: #f8f9fa;
+        color: #5f6368;
+        font-weight: 600;
+        font-size: 13px;
+        text-transform: uppercase;
+        padding: 0 16px;
+        height: 48px;
+        border-bottom: 1px solid #e0e0e0;
+    }
+
+    td.mat-cell {
+        padding: 0 16px;
+        font-size: 14px;
+        color: #3c4043;
+        height: 48px;
+        border-bottom: 1px solid #f1f3f4;
+    }
+
+    tr.mat-row:hover {
+        background-color: #f8f9fa;
+    }
+
+    .row-link {
+        color: #1967d2;
+        text-decoration: none;
+        cursor: pointer;
+        font-weight: 500;
+
+        &:hover {
+            text-decoration: underline;
+        }
+    }
+
+    .secondary-text {
+        color: #5f6368;
+    }
+
+    .status-cell {
+        display: flex;
+        align-items: center;
+        gap: 8px;
+        font-weight: 500;
+
+        .success-icon {
+            color: #137333;
+        }
+
+        .error-icon {
+            color: #d32f2f;
+        }
+
+        .status-text {
+            &.success {
+                color: #137333;
+            }
+
+            &.error {
+                color: #d32f2f;
+            }
+        }
+    }
+
+    .row-action {
+        display: flex;
+        gap: 8px;
+        align-items: center;
+
+        button {
+            width: 32px;
+            height: 32px;
+            line-height: 32px;
+
+            fa-icon {
+                font-size: 14px;
+                color: #5f6368;
+            }
+
+            &:hover fa-icon {
+                color: #1967d2;
+            }
+
+            &[color="warn"]:hover fa-icon {
+                color: #d32f2f;
+            }
+        }
+    }
+
+    /* No Data Row */
+    .no-data-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 48px 0;
+        color: #757575;
+        gap: 12px;
+
+        fa-icon {
+            font-size: 40px;
+            opacity: 0.5;
+        }
+
+        span {
+            font-size: 14px;
+        }
+    }
+}
\ No newline at end of file
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 2820)
+++ /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)
@@ -1,17 +1,17 @@
-import {AfterViewInit, ChangeDetectorRef, Component, inject, OnDestroy, OnInit, ViewChild} from '@angular/core';
-import {SharedModule} from '../../../shared/shared-module';
-import {MatTableDataSource} from '@angular/material/table';
-import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog';
-import {MatPaginator} from '@angular/material/paginator';
-import {DeviceService} from '../../../services/device-service';
-import {take} from 'rxjs/operators';
-import {NotificationService} from '../../../services/notification';
-import {NewlineToBrPipe} from '../../../pipes/newline-to-br-pipe';
-import {Router} from '@angular/router';
-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';
+import { AfterViewInit, ChangeDetectorRef, Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { SharedModule } from '../../../shared/shared-module';
+import { MatTableDataSource } from '@angular/material/table';
+import { MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog';
+import { MatPaginator } from '@angular/material/paginator';
+import { DeviceService } from '../../../services/device-service';
+import { take } from 'rxjs/operators';
+import { NotificationService } from '../../../services/notification';
+import { NewlineToBrPipe } from '../../../pipes/newline-to-br-pipe';
+import { Router } from '@angular/router';
+import { CreateDeviceConfigDialog, ShowTasksByNameDialog } from '../device-backup-files/device-backup-files';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Subscription, forkJoin } from 'rxjs';
+import { GlobalSerialPipe } from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-config-overview',
@@ -43,12 +43,43 @@
   }
 
   ngOnInit() {
-    setTimeout(() => {
-      this.getDeviceConfigFiles();
-      this.getDeviceGroups();
-    })
+    this.loadData();
+  }
+
+  loadData() {
+    forkJoin({
+      groups: this._device.getDeviceGroups().pipe(take(1)),
+      configFiles: this._device.getDeviceConfigFiles().pipe(take(1))
+    }).subscribe({
+      next: (results: any) => {
+        // Process Groups Data
+        this.processGroupData(results.groups);
+
+        // Process Config Files
+        this.dataSource.data = this.analyzeBackupData(results.configFiles);
+        this.dataSource.paginator = this.paginator;
+        this.totalRecords = this.dataSource.data.length;
+        this._cdRef.detectChanges();
+      },
+      error: (error) => {
+        this._notification.showError(`Error loading data: ${error?.message || 'Unknown error'}`);
+      }
+    });
   }
 
+  processGroupData(data: any) {
+    this.devices = [];
+    this.groups = [];
+    this.deviceGroups = [];
+    this.devices = data.devices;
+    data.groups.forEach((group: any) => {
+      if (group?.device_list.length > 0) {
+        this.groups.push(group?.group_name);
+        this.deviceGroups.push(group);
+      }
+    });
+  }
+
   ngAfterViewInit() {
     this.dataSource.paginator = this.paginator;
     this._cdRef.detectChanges();
@@ -75,6 +106,13 @@
     // First pass: Identify all devices and initialize their last backup time
     data.forEach(entry => {
       if (entry.file_type === 'device') {
+        // If device_type is missing, try to find it in this.devices
+        if (!entry.device_type) {
+          const deviceDetails = this.devices.find((d: any) => d.name === entry.name);
+          if (deviceDetails) {
+            entry.device_type = deviceDetails.type;
+          }
+        }
         deviceEntries.push(entry);
         this.deviceLastBackupMap[entry.name] = null;
       }
@@ -83,7 +121,8 @@
     // Second pass: Find the latest backup for each device
     data.forEach(entry => {
       if (entry.file_type === 'backup' && entry.name) {
-        const deviceMatch = entry.name.match(/^([a-zA-Z0-9]+)-/);
+        // Updated regex to capture device name before the timestamp suffix, allowing for extensions
+        const deviceMatch = entry.name.match(/^(.*)-(\d{4}_\d{2}_\d{2}_\d{2}:\d{2}:\d{2})/);
         if (deviceMatch && deviceMatch[1]) {
           const deviceName = deviceMatch[1];
           const backupTime = new Date(entry.create_time);
@@ -113,6 +152,9 @@
       });
     });
 
+    // Update table data strictly based on devices found (or synced from device groups)
+    // If deviceEntries is empty but we have devices from getDeviceGroups, we might want to show them?
+    // Current logic relies on 'device' file_type entries in config_file list.
     return results;
   }
 
@@ -167,9 +209,6 @@
   }
 
   viewDeviceConfiguration(_device: any) {
-    this.dialogConfig.position = {
-      bottom: '0px', right: '0px',
-    }
     this.dialogConfig.disableClose = true;
     this.dialogConfig.width = '50%';
     this.dialogConfig.height = '80%';
@@ -183,7 +222,7 @@
 
   viewDeviceConfigFilesHistory(_device: any) {
     this._router.navigate(['/configuration-hub/backup', _device.name], {
-      state: {deviceDetails: this.deviceBackupsMap[_device.name]},
+      state: { deviceDetails: this.deviceBackupsMap[_device.name] },
     });
   }
 
@@ -228,21 +267,14 @@
   }
 
   getDeviceGroups(): void {
-    this.devices = [];
-    this.groups = [];
-    this.deviceGroups = []
+    // This method is kept for compatibility if needed, but loadData handles the logic now.
+    // Ideally, references to this should be removed or it should just call the service.
+    // For now, leaving it empty or simple wrapper as logic moved to processGroupData.
     this._device.getDeviceGroups()
       .pipe(take(1))
       .subscribe({
         next: (data: any) => {
-          this.devices = data.devices;
-          data.groups.forEach((group: any) => {
-            if (group?.device_list.length > 0) {
-              this.groups.push(group?.group_name);
-              this.deviceGroups.push(group);
-            }
-          })
-          this.dataSource = new MatTableDataSource(this.devices);
+          this.processGroupData(data);
         }, error: (error: { message: string; }) => {
           console.log(error);
           this._notification.showError(error.message);
@@ -279,17 +311,17 @@
   getDeviceConfig(deviceName: any) {
     this._device.getDeviceConfiguration(deviceName)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this.deviceConfig = result[1];
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this.deviceConfig = result[1];
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel(): void {
@@ -311,15 +343,15 @@
   configForm: FormGroup;
 
   configOptions: any = [
-    {value: 'immediate', label: 'Immediate'},
-    {value: 'deferred', label: 'Deferred'},
-    {value: 'loop', label: 'Loop'},
+    { value: 'immediate', label: 'Immediate' },
+    { value: 'deferred', label: 'Deferred' },
+    { value: 'loop', label: 'Loop' },
   ]
 
   intervalUnits: any = [
-    {value: 1, label: 'Hour'},
-    {value: 24, label: 'Day'},
-    {value: 168, label: 'Week'},
+    { value: 1, label: 'Hour' },
+    { value: 24, label: 'Day' },
+    { value: 168, label: 'Week' },
   ]
 
   constructor(
@@ -379,18 +411,18 @@
     payload.set('options', JSON.stringify(rawPayload));
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Device config check initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Device config check initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel(): void {
@@ -468,7 +500,8 @@
 
   ngOnInit() {
     setTimeout(() => {
-      if (this.data?.device?.device_type.toLowerCase() === 'apv' || this.data?.device?.device_type.toLowerCase() === 'vapv') {
+      const deviceType = this.data?.device?.device_type?.toLowerCase();
+      if (deviceType === 'apv' || deviceType === 'vapv') {
         this.getAPVVirtualServices(this.data?.device?.id);
       }
     })
@@ -510,18 +543,18 @@
     payload.set('options', JSON.stringify(rawPayload));
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Device config clone initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Device config clone initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel(): void {
@@ -586,18 +619,18 @@
     payload.set('options', JSON.stringify(rawPayload));
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Device config check initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Device config check initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel(): void {
@@ -638,15 +671,15 @@
   configForm: FormGroup;
 
   configOptions: any = [
-    {value: 'immediate', label: 'Immediate'},
-    {value: 'deferred', label: 'Deferred'},
-    {value: 'loop', label: 'Loop'},
+    { value: 'immediate', label: 'Immediate' },
+    { value: 'deferred', label: 'Deferred' },
+    { value: 'loop', label: 'Loop' },
   ]
 
   intervalUnits: any = [
-    {value: 1, label: 'Hour'},
-    {value: 24, label: 'Day'},
-    {value: 168, label: 'Week'},
+    { value: 1, label: 'Hour' },
+    { value: 24, label: 'Day' },
+    { value: 168, label: 'Week' },
   ]
 
   constructor(
@@ -704,12 +737,14 @@
         this.data.deviceGroups.forEach((_dGroup: any) => {
           if (_group === _dGroup?.group_name) {
             _dGroup?.device_list.forEach((_device: any) => {
-              pk.push(JSON.stringify({
-                name: this.data.backup[_device?.name][0].name,
-                file_type: this.data.backup[_device?.name][0].file_type,
-                device_type: this.data.backup[_device?.name][0].device_type,
-                device_name: this.data.backup[_device?.name][0].device_name,
-              }))
+              if (this.data.backup[_device?.name] && this.data.backup[_device?.name].length > 0) {
+                pk.push(JSON.stringify({
+                  name: this.data.backup[_device?.name][0].name,
+                  file_type: this.data.backup[_device?.name][0].file_type,
+                  device_type: this.data.backup[_device?.name][0].device_type,
+                  device_name: this.data.backup[_device?.name][0].device_name,
+                }))
+              }
             })
           }
         })
@@ -729,18 +764,18 @@
     payload.set('options', JSON.stringify(rawPayload));
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Device config check initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Device config check initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel(): void {
@@ -807,10 +842,10 @@
   configForm: FormGroup;
 
   intervalUnits: any = [
-    {value: 'minutes', label: 'Minutes'},
-    {value: 'hours', label: 'Hours'},
-    {value: 'days', label: 'Days'},
-    {value: 'weeks', label: 'Weeks'},
+    { value: 'minutes', label: 'Minutes' },
+    { value: 'hours', label: 'Hours' },
+    { value: 'days', label: 'Days' },
+    { value: 'weeks', label: 'Weeks' },
   ]
   task_name_list: any = [];
   isScheduled: boolean = false;
@@ -844,30 +879,30 @@
   getScheduleDeviceBackup() {
     this._device.getScheduleDeviceBackup()
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result?.status && result?.data) {
-          this.configForm.patchValue({
-            devices: result?.data?.device_name,
-            interval: result?.data?.interval,
-            unit: result?.data?.unit,
-          })
-          this.task_name_list = result?.data?.task_name;
-          if (this.task_name_list.length > 0) {
-            this.isScheduled = true;
-            this.configForm.get('device')?.disable();
-            this.configForm.get('devices')?.disable();
-            this.configForm.get('device_groups')?.disable();
-            this.configForm.get('interval')?.disable();
-            this.configForm.get('unit')?.disable();
+        next: (result: any) => {
+          if (result && result?.status && result?.data) {
+            this.configForm.patchValue({
+              devices: result?.data?.device_name,
+              interval: result?.data?.interval,
+              unit: result?.data?.unit,
+            })
+            this.task_name_list = result?.data?.task_name;
+            if (this.task_name_list.length > 0) {
+              this.isScheduled = true;
+              this.configForm.get('device')?.disable();
+              this.configForm.get('devices')?.disable();
+              this.configForm.get('device_groups')?.disable();
+              this.configForm.get('interval')?.disable();
+              this.configForm.get('unit')?.disable();
+            }
           }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onSubmit(): void {
@@ -897,18 +932,18 @@
     payload.set('options', JSON.stringify(rawPayload));
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Device config check initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Device config check initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   clearScheduleDeviceBackup(): void {
@@ -916,18 +951,18 @@
     payload.set('task_name_list', JSON.stringify(this.task_name_list));
     this._device.clearScheduleDeviceBackup(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.state) {
-          this._notification.showSuccess(`Device scheduled backup has been cleared successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.state) {
+            this._notification.showSuccess(`Device scheduled backup has been cleared successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel(): void {
@@ -1059,18 +1094,18 @@
     payload.set('options', JSON.stringify(devicePayload));
     this._device.performDeviceConfigOperation(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.length > 1) {
-          this._notification.showSuccess(`Device config check initiated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.length > 1) {
+            this._notification.showSuccess(`Device config check initiated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   private applyDeviceGroupsValidation(): void {
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/show-device-config.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/show-device-config.html	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-config-overview/show-device-config.html	(working copy)
@@ -4,11 +4,8 @@
   <div [innerHTML]="deviceConfig | newlineToBr" class="wrapped-text"></div>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button
-    mat-button
-    color="basic"
-    (click)="onCancel()">
-    Cancel
+  <button mat-button color="basic" (click)="onCancel()">
+    Close
   </button>
 </mat-dialog-actions>
 
@@ -17,5 +14,4 @@
     word-wrap: break-word;
     overflow-wrap: break-word;
   }
-
-</style>
+</style>
\ No newline at end of file
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 2820)
+++ /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)
@@ -1,62 +1,82 @@
-<div class="button-container">
-  <button mat-raised-button (click)="addCustomConfig()">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 | globalSerial }}</td>
-    </ng-container>
-    <ng-container matColumnDef="deviceName">
-      <th mat-header-cell *matHeaderCellDef>Configuration Filename</th>
-      <td mat-cell *matCellDef="let element">
-        <a class="details-page-link" (click)="editDeviceConfiguration(element)">{{ element.name }}</a>
-      </td>
-    </ng-container>
-    <ng-container matColumnDef="fileType">
-      <th mat-header-cell *matHeaderCellDef>File Type</th>
-      <td mat-cell *matCellDef="let element"> {{ element.file_type }}</td>
-    </ng-container>
-    <ng-container matColumnDef="deviceType">
-      <th mat-header-cell *matHeaderCellDef>Device Type</th>
-      <td mat-cell *matCellDef="let element"> {{ element.device_type }}</td>
-    </ng-container>
-    <ng-container matColumnDef="createTime">
-      <th mat-header-cell *matHeaderCellDef>Create Time</th>
-      <td mat-cell *matCellDef="let element">{{ element.create_time }}</td>
-    </ng-container>
-    <ng-container matColumnDef="cloneSource">
-      <th mat-header-cell *matHeaderCellDef>Modify Time</th>
-      <td mat-cell *matCellDef="let element">{{ element.modify_time }}</td>
-    </ng-container>
-    <ng-container matColumnDef="comment">
-      <th mat-header-cell *matHeaderCellDef>Comment</th>
-      <td mat-cell *matCellDef="let element">{{ element.comment }}</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]="['fas', 'code-compare']" size="lg" matTooltip="Compare configuration"
-                   (click)="compareConfiguration(element)"></fa-icon>
-          <fa-icon [icon]="['fas', 'gears']" size="lg" matTooltip="Apply configuration"
-                   (click)="applyConfiguration(element)"></fa-icon>
-          <fa-icon [icon]="['fas', 'list-check']" size="lg" matTooltip="Task for this configuration"
-                   (click)="showTaskConfiguration(element)"></fa-icon>
-          <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete configuration"
-                   (click)="deleteConfiguration(element)"></fa-icon>
-        </div>
-      </td>
-    </ng-container>
-    <tr mat-header-row *matHeaderRowDef="deviceColumns"></tr>
-    <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
-    <tr class="mat-row table-no-data" *matNoDataRow>
-      <td class="mat-cell" colspan="11">No results found.</td>
-    </tr>
-  </table>
-  <mat-paginator
-    [pageSizeOptions]="[10, 15, 20, 25]"
-    [length]="totalRecords"
-    showFirstLastButtons
-  ></mat-paginator>
-</div>
+<div class="page-container">
+  <mat-card class="table-card appearance-outlined">
+    <mat-card-header>
+      <mat-card-title>Custom Configuration</mat-card-title>
+      <div class="header-actions">
+        <button mat-flat-button color="primary" (click)="addCustomConfig()">
+          <fa-icon [icon]="['fas', 'plus']"></fa-icon> Add Configuration
+        </button>
+      </div>
+    </mat-card-header>
+    <mat-card-content>
+      <div class="table-wrapper">
+        <table mat-table [dataSource]="dataSource" class="modern-table">
+          <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="deviceName">
+            <th mat-header-cell *matHeaderCellDef>Configuration Filename</th>
+            <td mat-cell *matCellDef="let element">
+              <a class="row-link" (click)="editDeviceConfiguration(element)">{{ element.name }}</a>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="fileType">
+            <th mat-header-cell *matHeaderCellDef>File Type</th>
+            <td mat-cell *matCellDef="let element">
+              <span class="badge" [ngClass]="element.file_type">{{ element.file_type }}</span>
+            </td>
+          </ng-container>
+          <ng-container matColumnDef="deviceType">
+            <th mat-header-cell *matHeaderCellDef>Device Type</th>
+            <td mat-cell *matCellDef="let element"> {{ element.device_type }}</td>
+          </ng-container>
+          <ng-container matColumnDef="createTime">
+            <th mat-header-cell *matHeaderCellDef>Create Time</th>
+            <td mat-cell *matCellDef="let element" class="secondary-text">{{ element.create_time }}</td>
+          </ng-container>
+          <ng-container matColumnDef="cloneSource">
+            <th mat-header-cell *matHeaderCellDef>Modify Time</th>
+            <td mat-cell *matCellDef="let element" class="secondary-text">{{ element.modify_time }}</td>
+          </ng-container>
+          <ng-container matColumnDef="comment">
+            <th mat-header-cell *matHeaderCellDef>Comment</th>
+            <td mat-cell *matCellDef="let element" class="secondary-text">{{ element.comment }}</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">
+                <button mat-icon-button matTooltip="Compare configuration" (click)="compareConfiguration(element)">
+                  <fa-icon [icon]="['fas', 'code-compare']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Apply configuration" (click)="applyConfiguration(element)">
+                  <fa-icon [icon]="['fas', 'gears']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button matTooltip="Task for this configuration"
+                  (click)="showTaskConfiguration(element)">
+                  <fa-icon [icon]="['fas', 'list-check']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button color="warn" matTooltip="Delete configuration"
+                  (click)="deleteConfiguration(element)">
+                  <fa-icon [icon]="['far', 'trash-can']" size="lg"></fa-icon>
+                </button>
+              </div>
+            </td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="deviceColumns; sticky: true"></tr>
+          <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="8">
+              <div class="no-data-content">
+                <fa-icon [icon]="['far', 'folder-open']"></fa-icon>
+                <span>No configuration files found</span>
+              </div>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <mat-paginator [pageSizeOptions]="[10, 15, 20, 25]" [length]="totalRecords" showFirstLastButtons></mat-paginator>
+    </mat-card-content>
+  </mat-card>
+</div>
\ No newline at end of file
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.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.scss	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-overview/device-custom-config-overview.scss	(working copy)
@@ -0,0 +1,172 @@
+.page-container {
+    padding: 16px;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    box-sizing: border-box;
+}
+
+mat-card.table-card {
+    display: flex;
+    flex-direction: column;
+    flex: 1;
+    overflow: hidden;
+    border-radius: 8px;
+    background: #fff;
+    border: none;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+
+    &.appearance-outlined {
+        border: 1px solid #e0e0e0;
+        box-shadow: none;
+    }
+
+    mat-card-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        padding: 16px;
+        border-bottom: 1px solid #f0f0f0;
+
+        mat-card-title {
+            font-size: 18px;
+            font-weight: 500;
+            margin: 0;
+        }
+
+        .header-actions {
+            display: flex;
+            gap: 8px;
+
+            button {
+                display: flex;
+                align-items: center;
+                gap: 8px;
+
+                fa-icon {
+                    font-size: 14px;
+                }
+            }
+        }
+    }
+
+    mat-card-content {
+        flex: 1;
+        display: flex;
+        flex-direction: column;
+        padding: 0;
+        overflow: hidden;
+
+        .table-wrapper {
+            flex: 1;
+            overflow: auto;
+        }
+    }
+}
+
+table.modern-table {
+    width: 100%;
+
+    th.mat-header-cell {
+        background-color: #f8f9fa;
+        color: #5f6368;
+        font-weight: 600;
+        font-size: 13px;
+        text-transform: uppercase;
+        padding: 0 16px;
+        height: 48px;
+        border-bottom: 1px solid #e0e0e0;
+    }
+
+    td.mat-cell {
+        padding: 0 16px;
+        font-size: 14px;
+        color: #3c4043;
+        height: 48px;
+        border-bottom: 1px solid #f1f3f4;
+    }
+
+    tr.mat-row:hover {
+        background-color: #f8f9fa;
+    }
+
+    .row-link {
+        color: #1967d2;
+        text-decoration: none;
+        cursor: pointer;
+        font-weight: 500;
+
+        &:hover {
+            text-decoration: underline;
+        }
+    }
+
+    .secondary-text {
+        color: #5f6368;
+    }
+
+    .badge {
+        padding: 2px 8px;
+        border-radius: 4px;
+        font-size: 12px;
+        font-weight: 500;
+        background-color: #e8f0fe;
+        color: #1a73e8;
+
+        &.template {
+            background-color: #e6f4ea;
+            color: #137333;
+        }
+
+        &.customize {
+            background-color: #fff8e1;
+            color: #f9a825;
+        }
+    }
+
+    .row-action {
+        display: flex;
+        gap: 8px;
+        align-items: center;
+
+        button {
+            width: 32px;
+            height: 32px;
+            line-height: 32px;
+
+            fa-icon {
+                font-size: 14px;
+                color: #5f6368;
+            }
+
+            &:hover fa-icon {
+                color: #1967d2;
+            }
+
+            &[color="warn"]:hover fa-icon {
+                color: #d32f2f;
+            }
+        }
+    }
+
+    /* No Data Row */
+    .no-data-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 48px 0;
+        color: #757575;
+        gap: 12px;
+
+        fa-icon {
+            font-size: 40px;
+            opacity: 0.5;
+        }
+
+        span {
+            font-size: 14px;
+        }
+    }
+}
\ No newline at end of file
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 2820)
+++ /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)
@@ -1,23 +1,24 @@
-import {AfterViewInit, ChangeDetectorRef, Component, inject, OnDestroy, OnInit, ViewChild} from '@angular/core';
-import {SharedModule} from '../../../shared/shared-module';
-import {MatTableDataSource} from '@angular/material/table';
-import {MatPaginator} from '@angular/material/paginator';
-import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog';
-import {DeviceService} from '../../../services/device-service';
-import {NotificationService} from '../../../services/notification';
-import {Router} from '@angular/router';
-import {take} from 'rxjs/operators';
+import { AfterViewInit, ChangeDetectorRef, Component, inject, OnDestroy, OnInit, ViewChild } from '@angular/core';
+import { SharedModule } from '../../../shared/shared-module';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog';
+import { DeviceService } from '../../../services/device-service';
+import { NotificationService } from '../../../services/notification';
+import { Router } from '@angular/router';
+import { take } from 'rxjs/operators';
 import {
   ApplyConfigurationDialog,
   CompareCloneConfigDialog,
   EditConfigurationDialog
 } from '../device-cloned-files/device-cloned-files';
-import {Confirmation} from '../../../services/confirmation';
-import {ShowTasksByNameDialog} from '../device-backup-files/device-backup-files';
-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';
+import { Confirmation } from '../../../services/confirmation';
+import { ShowTasksByNameDialog } from '../device-backup-files/device-backup-files';
+import { FormBuilder, FormGroup, Validators } from '@angular/forms';
+import { Storage } from '../../../services/storage';
+import { SystemService } from '../../../services/system-service';
+import { UtilsService } from '../../../services/utils-service';
+import { GlobalSerialPipe } from '../../../pipes/global-serial-pipe';
 
 @Component({
   selector: 'app-device-custom-config-overview',
@@ -45,6 +46,7 @@
     private _notification: NotificationService,
     private _router: Router,
     private _confirmation: Confirmation,
+    private _utils: UtilsService,
   ) {
   }
 
@@ -127,20 +129,29 @@
       })
   }
 
-  editDeviceConfiguration(_config: any) {
-    this.dialogConfig.data = {
-      config: _config,
+  editDeviceConfiguration(_device: any) {
+    const dialogConfig = new MatDialogConfig();
+    dialogConfig.position = {
+      bottom: '0px', right: '0px',
+    }
+    dialogConfig.disableClose = true;
+    dialogConfig.width = '50%';
+    dialogConfig.height = '80%';
+    dialogConfig.data = {
+      config: _device,
     };
-    const dialogRef = this.dialog.open(EditConfigurationDialog, this.dialogConfig);
+    const dialogRef = this.dialog.open(EditConfigurationDialog, dialogConfig);
     dialogRef.afterClosed().subscribe(() => {
     })
   }
 
   compareConfiguration(_config: any) {
+    let _devices = this._utils.getAssociatedDevices(_config?.device_type, this.groupedDevices);
+
     this.dialogConfig.width = '60%';
     this.dialogConfig.data = {
       device: _config,
-      devices: this.groupedDevices[_config?.device_type],
+      devices: _devices,
     }
     const dialogRef = this.dialog.open(CompareCloneConfigDialog, this.dialogConfig);
     dialogRef.afterClosed().subscribe((result: boolean) => {
@@ -148,10 +159,11 @@
   }
 
   applyConfiguration(_config: any) {
+    let _devices = this._utils.getAssociatedDevices(_config?.device_type, this.groupedDevices);
     this.dialogConfig.width = '60%';
     this.dialogConfig.data = {
       device: _config,
-      devices: this.groupedDevices[_config?.device_type],
+      devices: _devices,
       groups: this.groups
     }
     const dialogRef = this.dialog.open(ApplyConfigurationDialog, this.dialogConfig);
@@ -169,12 +181,12 @@
   }
 
   deleteConfiguration(_config: any) {
-    let confirmMsg = `Are you sure you want to delete the configuration file - ${_config?.name}"?`
+    let confirmMsg = `Are you sure you want to delete the configuration file - "${_config?.name}"?`
     this._confirmation.openConfirmDialog({
       title: `Delete Configuration File?`,
       message: confirmMsg,
-      confirmButtonText: 'Yes, Delete It',
-      cancelButtonText: 'No, Keep It',
+      confirmButtonText: 'Delete',
+      cancelButtonText: 'Cancel',
       confirmButtonColor: 'warn',
       cancelButtonColor: 'primary'
     }).subscribe((result: boolean) => {
@@ -230,9 +242,9 @@
   deviceTypes: any = [];
 
   configOption: any = [
-    {value: 'text', label: 'Text Configuration'},
-    {value: 'file', label: 'File Configuration'},
-    {value: 'template', label: 'Template Configuration'},
+    { value: 'text', label: 'Text Configuration' },
+    { value: 'file', label: 'File Configuration' },
+    { value: 'template', label: 'Template Configuration' },
   ]
   selectedFile: File | null = null;
   fileContent: any = null;
@@ -261,8 +273,8 @@
       cert_type: [''],
       password: [''],
       servername: [''],
-      template_content: [{value: '', disabled: true}],
-      config_preview: [{value: '', disabled: true}],
+      template_content: [{ value: '', disabled: true }],
+      config_preview: [{ value: '', disabled: true }],
     });
     this.setupConditionalValidation();
     this.onTemplateChange();
@@ -462,17 +474,17 @@
     payload.append('file', file, file.name);
     this._system.upload(null, payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result.files) {
-          if (result.files.length > 0) {
-            this.upload_path = result.files[0].url;
+        next: (result: any) => {
+          if (result.files) {
+            if (result.files.length > 0) {
+              this.upload_path = result.files[0].url;
+            }
           }
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
         }
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-      }
-    })
+      })
   }
 
   onTemplateChange(): void {
@@ -532,20 +544,20 @@
     payload.set('post_data', JSON.stringify(rawPayload));
     this._device.addCustomConfigFile(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result[0]) {
-          this._notification.showSuccess(`The custom configuration has been updated successfully.`);
-          this.dialogRef.close(true);
-        } else {
-          this._notification.showError(`Failed to add the custom configuration: ${result[1]}`);
+        next: (result: any) => {
+          if (result && result[0]) {
+            this._notification.showSuccess(`The custom configuration has been updated successfully.`);
+            this.dialogRef.close(true);
+          } else {
+            this._notification.showError(`Failed to add the custom configuration: ${result[1]}`);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   ngOnDestroy() {
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 2820)
+++ /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)
@@ -1,96 +1,114 @@
-<mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <mat-card-title>Templates</mat-card-title>
-  </mat-card-header>
-  <div class="button-container">
-    <button mat-raised-button (click)="addCustomTemplate()">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 | globalSerial }}</td>
-      </ng-container>
-      <ng-container matColumnDef="tKey">
-        <th mat-header-cell *matHeaderCellDef>Template Keyword</th>
-        <td mat-cell *matCellDef="let element"> {{ element.key }}</td>
-      </ng-container>
-      <ng-container matColumnDef="tDescription">
-        <th mat-header-cell *matHeaderCellDef>Description</th>
-        <td mat-cell *matCellDef="let element"> {{ element.description }}</td>
-      </ng-container>
-      <ng-container matColumnDef="tDefault">
-        <th mat-header-cell *matHeaderCellDef>Default Value</th>
-        <td mat-cell *matCellDef="let element">{{ element.default_value }}</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" matTooltip="Edit"
-                     (click)="editTemplateKey(element)"></fa-icon>
-            <fa-icon [icon]="['far', 'trash-can']" size="lg" class="delete-icon" matTooltip="Delete"
-                     (click)="deleteTemplateKey(element)"></fa-icon>
-          </div>
-        </td>
-      </ng-container>
-      <tr mat-header-row *matHeaderRowDef="deviceColumns"></tr>
-      <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
-      <tr class="mat-row table-no-data" *matNoDataRow>
-        <td class="mat-cell" colspan="11">No results found.</td>
-      </tr>
-    </table>
-    <mat-paginator
-      [pageSizeOptions]="[10, 15, 20, 25]"
-      [length]="totalRecords"
-      showFirstLastButtons
-    ></mat-paginator>
-  </div>
-</mat-card>
+<div class="page-container">
+  <mat-card class="table-card appearance-outlined">
+    <mat-card-header>
+      <mat-card-title>Templates</mat-card-title>
+      <div class="header-actions">
+        <button mat-flat-button color="primary" (click)="addCustomTemplate()">
+          <fa-icon [icon]="['fas', 'plus']"></fa-icon> Add Template
+        </button>
+      </div>
+    </mat-card-header>
+    <mat-card-content>
+      <div class="table-wrapper">
+        <table mat-table [dataSource]="dataSource" class="modern-table">
+          <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="tKey">
+            <th mat-header-cell *matHeaderCellDef>Template Keyword</th>
+            <td mat-cell *matCellDef="let element"> {{ element.key }}</td>
+          </ng-container>
+          <ng-container matColumnDef="tDescription">
+            <th mat-header-cell *matHeaderCellDef>Description</th>
+            <td mat-cell *matCellDef="let element"> {{ element.description }}</td>
+          </ng-container>
+          <ng-container matColumnDef="tDefault">
+            <th mat-header-cell *matHeaderCellDef>Default Value</th>
+            <td mat-cell *matCellDef="let element">{{ element.default_value }}</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">
+                <button mat-icon-button matTooltip="Edit" (click)="editTemplateKey(element)">
+                  <fa-icon [icon]="['far', 'edit']" size="lg"></fa-icon>
+                </button>
+                <button mat-icon-button color="warn" matTooltip="Delete" (click)="deleteTemplateKey(element)">
+                  <fa-icon [icon]="['far', 'trash-can']" size="lg"></fa-icon>
+                </button>
+              </div>
+            </td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="deviceColumns; sticky: true"></tr>
+          <tr mat-row *matRowDef="let row; columns: deviceColumns;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="5">
+              <div class="no-data-content">
+                <fa-icon [icon]="['far', 'folder-open']"></fa-icon>
+                <span>No templates found</span>
+              </div>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <mat-paginator #paginator [pageSizeOptions]="[10, 15, 20, 25]" [length]="totalRecords"
+        showFirstLastButtons></mat-paginator>
+    </mat-card-content>
+  </mat-card>
 
-<mat-card class="page-card-1" appearance="filled">
-  <mat-card-header>
-    <mat-card-title>Device Template Parameters</mat-card-title>
-  </mat-card-header>
-  <div class="table-container">
-    <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;"> {{ i | globalSerial }}</td>
-      </ng-container>
-      <ng-container matColumnDef="device">
-        <th mat-header-cell *matHeaderCellDef>Device IP</th>
-        <td mat-cell *matCellDef="let element"> {{ element?.device_ip }}</td>
-      </ng-container>
-      <ng-container matColumnDef="template">
-        <th mat-header-cell *matHeaderCellDef>Template</th>
-        <td mat-cell *matCellDef="let element">
-          @for (key of Object.keys(element); track key) {
-            @if (key !== 'device_ip') {
-              <span> {{ key }} : {{ element[key] }}</span><br>
-            }
-          }
-        </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" matTooltip="Edit"
-                     (click)="editDeviceTemplateConfig(element)"></fa-icon>
-          </div>
-        </td>
-      </ng-container>
-      <tr mat-header-row *matHeaderRowDef="deviceColumns1"></tr>
-      <tr mat-row *matRowDef="let row; columns: deviceColumns1;"></tr>
-      <tr class="mat-row table-no-data" *matNoDataRow>
-        <td class="mat-cell" colspan="11">No results found.</td>
-      </tr>
-    </table>
-    <mat-paginator
-      [pageSizeOptions]="[10, 15, 20, 25]"
-      [length]="totalRecords1"
-      showFirstLastButtons
-    ></mat-paginator>
-  </div>
-</mat-card>
+  <mat-card class="table-card appearance-outlined">
+    <mat-card-header>
+      <mat-card-title>Device Template Parameters</mat-card-title>
+    </mat-card-header>
+    <mat-card-content>
+      <div class="table-wrapper">
+        <table mat-table [dataSource]="dataSource1" class="modern-table">
+          <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="device">
+            <th mat-header-cell *matHeaderCellDef>Device IP</th>
+            <td mat-cell *matCellDef="let element"> {{ element?.device_ip }}</td>
+          </ng-container>
+          <ng-container matColumnDef="template">
+            <th mat-header-cell *matHeaderCellDef>Template</th>
+            <td mat-cell *matCellDef="let element">
+              @for (key of Object.keys(element); track key) {
+              @if (key !== 'device_ip') {
+              <div class="template-param">
+                <span class="param-key">{{ key }}:</span>
+                <span class="param-value">{{ element[key] }}</span>
+              </div>
+              }
+              }
+            </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">
+                <button mat-icon-button matTooltip="Edit" (click)="editDeviceTemplateConfig(element)">
+                  <fa-icon [icon]="['far', 'edit']" size="lg"></fa-icon>
+                </button>
+              </div>
+            </td>
+          </ng-container>
+          <tr mat-header-row *matHeaderRowDef="deviceColumns1; sticky: true"></tr>
+          <tr mat-row *matRowDef="let row; columns: deviceColumns1;"></tr>
+          <tr class="mat-row table-no-data" *matNoDataRow>
+            <td class="mat-cell" colspan="4">
+              <div class="no-data-content">
+                <fa-icon [icon]="['far', 'folder-open']"></fa-icon>
+                <span>No device template parameters found</span>
+              </div>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <mat-paginator #paginator1 [pageSizeOptions]="[10, 15, 20, 25]" [length]="totalRecords1"
+        showFirstLastButtons></mat-paginator>
+    </mat-card-content>
+  </mat-card>
+</div>
\ No newline at end of file
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.scss
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.scss	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/device-custom-config-templates.scss	(working copy)
@@ -0,0 +1,171 @@
+:host {
+    height: 100%;
+    display: block;
+}
+
+.page-container {
+    padding: 16px;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    gap: 16px;
+    overflow: hidden; // Prevent outer scroll
+    box-sizing: border-box; // Include padding in height calculation
+}
+
+mat-card.table-card {
+    display: flex;
+    flex-direction: column;
+    flex: 1; // Take equal available space
+    min-height: 0; // Allow shrinking for nested scrolling
+    overflow: hidden;
+    border-radius: 8px;
+    background: #fff;
+    border: none;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+
+    &.appearance-outlined {
+        border: 1px solid #e0e0e0;
+        box-shadow: none;
+    }
+
+    mat-card-header {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        height: 60px; // Fixed height
+        max-height: 60px;
+        padding: 0 16px; // Adjust padding since height is fixed
+        border-bottom: 1px solid #f0f0f0;
+        box-sizing: border-box;
+
+        mat-card-title {
+            font-size: 18px;
+            font-weight: 500;
+            margin: 0;
+            line-height: normal;
+        }
+
+        .header-actions {
+            display: flex;
+            gap: 8px;
+
+            button {
+                display: flex;
+                align-items: center;
+                gap: 8px;
+
+                fa-icon {
+                    font-size: 14px;
+                }
+            }
+        }
+    }
+
+    mat-card-content {
+        display: flex;
+        flex-direction: column;
+        padding: 0;
+        overflow: hidden;
+        flex: 1; // Fill remaining card space
+        min-height: 0; // Fix for nested flex scrolling
+
+        .table-wrapper {
+            flex: 1; // Fill available content space
+            overflow: auto; // Scroll internally
+            min-height: 0; // Fix for nested flex scrolling
+            // max-height: 400px; // Removed to allow full height usage
+        }
+
+        mat-paginator {
+            border-top: 1px solid #e0e0e0;
+        }
+    }
+}
+
+table.modern-table {
+    width: 100%;
+
+    th.mat-header-cell {
+        background-color: #f8f9fa;
+        color: #5f6368;
+        font-weight: 600;
+        font-size: 13px;
+        text-transform: uppercase;
+        padding: 0 16px;
+        height: 48px;
+        border-bottom: 1px solid #e0e0e0;
+    }
+
+    td.mat-cell {
+        padding: 0 16px;
+        font-size: 14px;
+        color: #3c4043;
+        height: 48px;
+        border-bottom: 1px solid #f1f3f4;
+    }
+
+    tr.mat-row:hover {
+        background-color: #f8f9fa;
+    }
+
+    .template-param {
+        display: flex;
+        gap: 8px;
+        font-size: 13px;
+
+        .param-key {
+            color: #5f6368;
+            font-weight: 500;
+        }
+
+        .param-value {
+            color: #3c4043;
+        }
+    }
+
+    .row-action {
+        display: flex;
+        gap: 8px;
+        align-items: center;
+
+        button {
+            width: 32px;
+            height: 32px;
+            line-height: 32px;
+
+            fa-icon {
+                font-size: 14px;
+                color: #5f6368;
+            }
+
+            &:hover fa-icon {
+                color: #1967d2;
+            }
+
+            &[color="warn"]:hover fa-icon {
+                color: #d32f2f;
+            }
+        }
+    }
+
+    /* No Data Row */
+    .no-data-content {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        padding: 48px 0;
+        color: #757575;
+        gap: 12px;
+
+        fa-icon {
+            font-size: 40px;
+            opacity: 0.5;
+        }
+
+        span {
+            font-size: 14px;
+        }
+    }
+}
\ No newline at end of file
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 2820)
+++ /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)
@@ -1,15 +1,15 @@
-import {AfterViewInit, ChangeDetectorRef, Component, inject, OnInit, ViewChild} from '@angular/core';
-import {MatTableDataSource} from '@angular/material/table';
-import {MatPaginator} from '@angular/material/paginator';
-import {MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef} from '@angular/material/dialog';
-import {DeviceService} from '../../../services/device-service';
-import {NotificationService} from '../../../services/notification';
-import {Router} from '@angular/router';
-import {Confirmation} from '../../../services/confirmation';
-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';
+import { AfterViewInit, ChangeDetectorRef, Component, inject, OnInit, ViewChild } from '@angular/core';
+import { MatTableDataSource } from '@angular/material/table';
+import { MatPaginator } from '@angular/material/paginator';
+import { MAT_DIALOG_DATA, MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog';
+import { DeviceService } from '../../../services/device-service';
+import { NotificationService } from '../../../services/notification';
+import { Router } from '@angular/router';
+import { Confirmation } from '../../../services/confirmation';
+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',
@@ -22,12 +22,12 @@
   totalRecords: number = 0;
   dataSource: MatTableDataSource<any> = new MatTableDataSource();
   deviceColumns: string[] = ['serial', 'tKey', 'tDescription', 'tDefault', 'action'];
-  @ViewChild(MatPaginator) paginator!: MatPaginator;
+  @ViewChild('paginator') paginator!: MatPaginator;
 
   totalRecords1: number = 0;
   dataSource1: MatTableDataSource<any> = new MatTableDataSource();
   deviceColumns1: string[] = ['serial', 'device', 'template', 'action'];
-  @ViewChild(MatPaginator) paginator1!: MatPaginator;
+  @ViewChild('paginator1') paginator1!: MatPaginator;
 
   dialog = inject(MatDialog);
   dialogConfig = new MatDialogConfig();
@@ -137,12 +137,12 @@
   }
 
   deleteTemplateKey(_template: any) {
-    let confirmMsg = `Are you sure you want to delete the template keyword - ${_template?.key}"?`
+    let confirmMsg = `Are you sure you want to delete the template keyword - "${_template?.key}"?`
     this._confirmation.openConfirmDialog({
       title: `Delete Configuration File?`,
       message: confirmMsg,
-      confirmButtonText: 'Yes, Delete It',
-      cancelButtonText: 'No, Keep It',
+      confirmButtonText: 'Delete',
+      cancelButtonText: 'Cancel',
       confirmButtonColor: 'warn',
       cancelButtonColor: 'primary'
     }).subscribe((result: boolean) => {
@@ -212,18 +212,18 @@
     }));
     this._device.addConfigTemplateKey(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.state) {
-          this._notification.showSuccess(`Template key has been added successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.state) {
+            this._notification.showSuccess(`Template key has been added successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel() {
@@ -276,18 +276,18 @@
     }));
     this._device.updateConfigTemplateKey(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.state) {
-          this._notification.showSuccess(`Template key has been updated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.state) {
+            this._notification.showSuccess(`Template key has been updated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel() {
@@ -345,26 +345,33 @@
     let rawPayload: any = [];
     let _obj = this.configForm.getRawValue();
     Object.keys(_obj).forEach((key: any) => {
-      rawPayload.push({key: key, value: _obj[key]});
+      rawPayload.push({ key: key, value: _obj[key] });
     })
     payload.set('post_data', JSON.stringify(rawPayload));
     this._device.updateDeviceConfigTemplateDefaultValue(payload)
       .pipe(take(1)).subscribe({
-      next: (result: any) => {
-        if (result && result.state) {
-          this._notification.showSuccess(`The device template key - default value has been updated successfully.`);
-          this.dialogRef.close(true);
+        next: (result: any) => {
+          if (result && result.state) {
+            this._notification.showSuccess(`The device template key - default value has been updated successfully.`);
+            this.dialogRef.close(true);
+          }
+          this._cdRef.detectChanges();
+        },
+        error: error => {
+          this._notification.showError(`Error: ${error?.message}`);
+          this._cdRef.detectChanges();
         }
-        this._cdRef.detectChanges();
-      },
-      error: error => {
-        this._notification.showError(`Error: ${error?.message}`);
-        this._cdRef.detectChanges();
-      }
-    })
+      })
   }
 
   onCancel() {
     this.dialogRef.close(false);
   }
+
+  formatLabel(key: string): string {
+    if (!key) return '';
+    const label = key.replace(/_/g, ' ');
+    const formatted = label.charAt(0).toUpperCase() + label.slice(1);
+    return formatted.replace(/\bip\b/gi, 'IP');
+  }
 }
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/edit-device-template-key-default-value.html
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/edit-device-template-key-default-value.html	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/components/sub-components/device-custom-config-templates/edit-device-template-key-default-value.html	(working copy)
@@ -1,36 +1,27 @@
 <h2 mat-dialog-title>Edit Device Template Key Default Value</h2>
 <mat-dialog-content>
-  <form
-    (ngSubmit)="onSubmit()"
-    [formGroup]="configForm"
-  >
+  <form (ngSubmit)="onSubmit()" [formGroup]="configForm">
     @for (formElement of formKeys; track formElement) {
-      <div class="form-field-wrapper">
-        <label for="formElement" class="form-label">{{ formElement }}</label>
-        <mat-form-field appearance="outline" subscriptSizing="dynamic">
-          <mat-label>{{ formElement | titlecase }}</mat-label>
-          <input [id]="formElement" matInput [formControlName]="formElement">
-          <mat-error>
-            @if (configForm.get(formElement)?.errors?.['required'] && configForm.get(formElement)?.touched) {
-              {{ formElement | titlecase }} is required.
-            }
-          </mat-error>
-        </mat-form-field>
-      </div>
+    <div class="form-field-wrapper">
+      <label for="formElement" class="form-label">{{ formatLabel(formElement) }}</label>
+      <mat-form-field appearance="outline" subscriptSizing="dynamic">
+        <mat-label>{{ formElement | titlecase }}</mat-label>
+        <input [id]="formElement" matInput [formControlName]="formElement">
+        <mat-error>
+          @if (configForm.get(formElement)?.errors?.['required'] && configForm.get(formElement)?.touched) {
+          {{ formElement | titlecase }} is required.
+          }
+        </mat-error>
+      </mat-form-field>
+    </div>
     }
   </form>
 </mat-dialog-content>
 <mat-dialog-actions>
-  <button
-    mat-button
-    color="basic"
-    (click)="onCancel()">
+  <button mat-button color="basic" (click)="onCancel()">
     Cancel
   </button>
-  <button
-    mat-raised-button
-    color="primary"
-    (click)="onSubmit()">
+  <button mat-raised-button color="primary" (click)="onSubmit()">
     Submit
   </button>
-</mat-dialog-actions>
+</mat-dialog-actions>
\ No newline at end of file
Index: /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/utils-service.ts
===================================================================
--- /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/utils-service.ts	(revision 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/services/utils-service.ts	(working copy)
@@ -1,6 +1,6 @@
-import {Injectable} from '@angular/core';
-import {MatTableDataSource} from '@angular/material/table';
-import {BytesPipe} from '../pipes/bytes-pipe';
+import { Injectable } from '@angular/core';
+import { MatTableDataSource } from '@angular/material/table';
+import { BytesPipe } from '../pipes/bytes-pipe';
 import { saveAs } from 'file-saver';
 
 export interface DeviceTypeStatus {
@@ -133,21 +133,21 @@
     if (metrics.includes('active_sessions')) {
       result.active_sessions = rawData
         .filter((item: any) => item.metric === 'active_sessions')
-        .map((item: any) => ({name: `${item.vsite_name} (${item.device_name || 'N/A'})`, value: item.value}))
+        .map((item: any) => ({ name: `${item.vsite_name} (${item.device_name || 'N/A'})`, value: item.value }))
         .sort((a: any, b: any) => b.value - a.value);
     }
 
     if (metrics.includes('cpu')) {
       result.cpu = rawData
         .filter((item: any) => item.metric === 'cpu')
-        .map((item: any) => ({name: `${item.device_name || 'N/A'}`, value: item.value}))
+        .map((item: any) => ({ name: `${item.device_name || 'N/A'}`, value: item.value }))
         .sort((a: any, b: any) => b.value - a.value);
     }
 
     if (metrics.includes('memory')) {
       result.memory = rawData
         .filter((item: any) => item.metric === 'memory')
-        .map((item: any) => ({name: `${item.device_name || 'N/A'}`, value: item.value}))
+        .map((item: any) => ({ name: `${item.device_name || 'N/A'}`, value: item.value }))
         .sort((a: any, b: any) => b.value - a.value);
     }
 
@@ -230,14 +230,14 @@
       connectedData.push(status.connected);
       disconnectedData.push(status.disconnected);
     });
-    return {yAxisData, connectedData, disconnectedData};
+    return { yAxisData, connectedData, disconnectedData };
   }
 
   transformTotalConnectedDevicesMetrics(devices: any): DeviceGraphData {
-    const totalStatus: DeviceTypeStatus = {connected: 0, disconnected: 0};
+    const totalStatus: DeviceTypeStatus = { connected: 0, disconnected: 0 };
     const typesStatus = new Map<string, DeviceTypeStatus>();
     if (!devices || devices.length === 0) {
-      return {total: totalStatus, types: typesStatus};
+      return { total: totalStatus, types: typesStatus };
     }
     devices.forEach((device: any) => {
       if (device.connection) {
@@ -246,7 +246,7 @@
         totalStatus.disconnected++;
       }
       if (!typesStatus.has(device.type)) {
-        typesStatus.set(device.type, {connected: 0, disconnected: 0});
+        typesStatus.set(device.type, { connected: 0, disconnected: 0 });
       }
       const status = typesStatus.get(device.type)!;
       if (device.connection) {
@@ -255,7 +255,7 @@
         status.disconnected++;
       }
     });
-    return {total: totalStatus, types: typesStatus};
+    return { total: totalStatus, types: typesStatus };
   }
 
   convertBytesForChart(data: any[], precision: number = 2): any[] {
@@ -283,25 +283,43 @@
     const p99_formatted: any = [];
 
     buckets
-        .forEach((d: any) => {
-          const timestamp = new Date(d.key_as_string).getTime();
-          const p50_val = d[key]?.values["50.0"] ?? 0;
-          const p95_val = d[key]?.values["95.0"] ?? 0;
-          const p99_val = d[key]?.values["99.0"] ?? 0;
-
-          const p50 = Number(p50_val.toFixed(2));
-          const p95 = Number(p95_val.toFixed(2));
-          const p99 = Number(p99_val.toFixed(2));
+      .forEach((d: any) => {
+        const timestamp = new Date(d.key_as_string).getTime();
+        const p50_val = d[key]?.values["50.0"] ?? 0;
+        const p95_val = d[key]?.values["95.0"] ?? 0;
+        const p99_val = d[key]?.values["99.0"] ?? 0;
 
-          p50_formatted.push([timestamp, p50]);
-          p95_formatted.push([timestamp, p95]);
-          p99_formatted.push([timestamp, p99]);
-        });
+        const p50 = Number(p50_val.toFixed(2));
+        const p95 = Number(p95_val.toFixed(2));
+        const p99 = Number(p99_val.toFixed(2));
 
+        p50_formatted.push([timestamp, p50]);
+        p95_formatted.push([timestamp, p95]);
+        p99_formatted.push([timestamp, p99]);
+      });
+
     return {
       p50_formatted,
       p95_formatted,
       p99_formatted
     };
   };
+  getAssociatedDevices(deviceType: string, groupedDevices: any): any[] {
+    let associatedType = '';
+    const type = deviceType || '';
+
+    if (type === 'APV') {
+      associatedType = 'vAPV';
+    } else if (type === 'AG') {
+      associatedType = 'vxAG';
+    } else if (type === 'ASF') {
+      associatedType = 'vASF';
+    }
+
+    const devices = groupedDevices[deviceType] ? [...groupedDevices[deviceType]] : [];
+    if (associatedType && groupedDevices[associatedType]) {
+      devices.push(...groupedDevices[associatedType]);
+    }
+    return devices;
+  }
 }
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 2820)
+++ /branches/amp_4_0/src/webui/webui/htdocs/new/src/gui/src/app/shared/shared-module.ts	(working copy)
@@ -78,7 +78,7 @@
   regularIcons.faCircleLeft, regularIcons.faSave, regularIcons.faCalendar, regularIcons.faEdit,
   regularIcons.faXmarkCircle, regularIcons.faBuilding, regularIcons.faPlayCircle,
   regularIcons.faCircleStop, regularIcons.faCopy, regularIcons.faClone, regularIcons.faClock,
-  regularIcons.faWindowRestore, regularIcons.faCircleUp,
+  regularIcons.faWindowRestore, regularIcons.faCircleUp, regularIcons.faFolderOpen
 ];
 
 const allCustomIcons = [...customSolidIcons, ...customRegularIcons];
