397 lines
17 KiB
PHP
397 lines
17 KiB
PHP
|
|
<?php
|
||
|
|
/* Smarty version 4.3.1, created on 2025-12-18 17:38:05
|
||
|
|
from '/var/www/html/yatmack/ui/ui/routers.tpl' */
|
||
|
|
|
||
|
|
/* @var Smarty_Internal_Template $_smarty_tpl */
|
||
|
|
if ($_smarty_tpl->_decodeProperties($_smarty_tpl, array (
|
||
|
|
'version' => '4.3.1',
|
||
|
|
'unifunc' => 'content_694411cd9a16a5_15764470',
|
||
|
|
'has_nocache_code' => false,
|
||
|
|
'file_dependency' =>
|
||
|
|
array (
|
||
|
|
'0a52be33c1eedc5833cca9edb209cb9489c25a1a' =>
|
||
|
|
array (
|
||
|
|
0 => '/var/www/html/yatmack/ui/ui/routers.tpl',
|
||
|
|
1 => 1757848876,
|
||
|
|
2 => 'file',
|
||
|
|
),
|
||
|
|
),
|
||
|
|
'includes' =>
|
||
|
|
array (
|
||
|
|
'file:sections/header.tpl' => 1,
|
||
|
|
'file:pagination.tpl' => 1,
|
||
|
|
'file:sections/footer.tpl' => 1,
|
||
|
|
),
|
||
|
|
),false)) {
|
||
|
|
function content_694411cd9a16a5_15764470 (Smarty_Internal_Template $_smarty_tpl) {
|
||
|
|
$_smarty_tpl->_subTemplateRender("file:sections/header.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, 0, $_smarty_tpl->cache_lifetime, array(), 0, false);
|
||
|
|
?>
|
||
|
|
<div class="container-fluid">
|
||
|
|
<div class="row">
|
||
|
|
<div class="col-sm-12">
|
||
|
|
<div class="card card-hovered mb20 card-primary">
|
||
|
|
<div class="card-header">
|
||
|
|
<h3 class="card-title"><?php echo Lang::T('Routers');?>
|
||
|
|
</h3>
|
||
|
|
</div>
|
||
|
|
<div class="card-body">
|
||
|
|
<div class="md-whiteframe-z1 mb20 text-center">
|
||
|
|
<div class="row">
|
||
|
|
<div class="col-md-8">
|
||
|
|
<form id="site-search" method="post" action="<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/list/">
|
||
|
|
<div class="input-group">
|
||
|
|
<div class="input-group-text">
|
||
|
|
<span class="fa fa-search"></span>
|
||
|
|
</div>
|
||
|
|
<input type="text" name="name" class="form-control"
|
||
|
|
placeholder="<?php echo Lang::T('Search by Name');?>
|
||
|
|
...">
|
||
|
|
<button class="btn btn-success input-group-btn" type="submit"><?php echo Lang::T('Search');?>
|
||
|
|
</button>
|
||
|
|
<!-- <div class="input-group-btn">
|
||
|
|
</div> -->
|
||
|
|
</div>
|
||
|
|
</form>
|
||
|
|
</div>
|
||
|
|
<div class="col-md-4">
|
||
|
|
<a href="<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/add" class="btn btn-primary btn-block"><i
|
||
|
|
class="fa fa-add"> </i> <?php echo Lang::T('New Router');?>
|
||
|
|
</a>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="table-responsive">
|
||
|
|
<table class="table table-bordered table-striped table-condensed">
|
||
|
|
<thead>
|
||
|
|
<tr>
|
||
|
|
<th><?php echo Lang::T('Router Name');?>
|
||
|
|
</th>
|
||
|
|
<th><?php echo Lang::T('IP Address');?>
|
||
|
|
</th>
|
||
|
|
<th><?php echo Lang::T('Status');?>
|
||
|
|
</th>
|
||
|
|
<th><?php echo Lang::T('Uptime');?>
|
||
|
|
</th>
|
||
|
|
<th><?php echo Lang::T('Free Memory');?>
|
||
|
|
</th>
|
||
|
|
<th><?php echo Lang::T('CPU Load');?>
|
||
|
|
</th>
|
||
|
|
<th><?php echo Lang::T('Manage');?>
|
||
|
|
</th>
|
||
|
|
<th>ID</th>
|
||
|
|
<th><?php echo Lang::T('Download');?>
|
||
|
|
</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody>
|
||
|
|
<?php
|
||
|
|
$_from = $_smarty_tpl->smarty->ext->_foreach->init($_smarty_tpl, $_smarty_tpl->tpl_vars['d']->value, 'ds');
|
||
|
|
$_smarty_tpl->tpl_vars['ds']->do_else = true;
|
||
|
|
if ($_from !== null) foreach ($_from as $_smarty_tpl->tpl_vars['ds']->value) {
|
||
|
|
$_smarty_tpl->tpl_vars['ds']->do_else = false;
|
||
|
|
?>
|
||
|
|
<tr <?php if ($_smarty_tpl->tpl_vars['ds']->value['enabled'] != 1) {?>class="danger" title="disabled" <?php }?>>
|
||
|
|
<td><?php echo $_smarty_tpl->tpl_vars['ds']->value['name'];?>
|
||
|
|
</td>
|
||
|
|
<td><?php echo $_smarty_tpl->tpl_vars['ds']->value['ip_address'];?>
|
||
|
|
</td>
|
||
|
|
<td class="router-status" data-router-id="<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
"><span class="loading-spinner"></span><span class="loader">Loading...</span></td>
|
||
|
|
<td class="router-uptime text-success" data-router-id="<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
"><span class="loading-spinner"></span><span class="loader">Loading...</span></td>
|
||
|
|
<td class="router-used-memory text-warning" data-router-id="<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
"><span class="loading-spinner"></span><span class="loader">Loading...</span></td>
|
||
|
|
<td class="router-cpu-load text-primary" data-router-id="<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
"><span class="loading-spinner"></span><span class="loader">Loading...</span></td>
|
||
|
|
<td>
|
||
|
|
<a href="<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/edit/<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
" class="btn btn-info btn-xs"><?php echo Lang::T('Edit');?>
|
||
|
|
</a>
|
||
|
|
<a href="<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/delete/<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
" id="<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
"
|
||
|
|
onclick="return confirm('<?php echo Lang::T('Delete');?>
|
||
|
|
?')"
|
||
|
|
class="btn btn-danger btn-xs"><i class="fa fa-trash"></i></a>
|
||
|
|
<button class="btn btn-warning btn-xs btn-reboot" data-router-id="<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
"><i class="fa fa-refresh"></i> <?php echo Lang::T('Reboot');?>
|
||
|
|
</button>
|
||
|
|
</td>
|
||
|
|
<td><?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
</td>
|
||
|
|
<td>
|
||
|
|
<form action="<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/download" method="post" style="display:inline;">
|
||
|
|
<input type="hidden" name="router_id" value="<?php echo $_smarty_tpl->tpl_vars['ds']->value['id'];?>
|
||
|
|
">
|
||
|
|
<input type="hidden" name="router_name" value="<?php echo $_smarty_tpl->tpl_vars['ds']->value['name'];?>
|
||
|
|
">
|
||
|
|
<button type="submit" class="btn btn-success btn-xs">
|
||
|
|
<i class="fa fa-download"></i> <?php echo Lang::T('Download');?>
|
||
|
|
|
||
|
|
</button>
|
||
|
|
</form>
|
||
|
|
</td>
|
||
|
|
</tr>
|
||
|
|
<?php
|
||
|
|
}
|
||
|
|
$_smarty_tpl->smarty->ext->_foreach->restore($_smarty_tpl, 1);?>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
<?php $_smarty_tpl->_subTemplateRender("file:pagination.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, 0, $_smarty_tpl->cache_lifetime, array(), 0, false);
|
||
|
|
?>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<?php $_smarty_tpl->_subTemplateRender("file:sections/footer.tpl", $_smarty_tpl->cache_id, $_smarty_tpl->compile_id, 0, $_smarty_tpl->cache_lifetime, array(), 0, false);
|
||
|
|
?>
|
||
|
|
|
||
|
|
<style>
|
||
|
|
.loader {
|
||
|
|
display: inline-block;
|
||
|
|
animation: loading 1.5s infinite;
|
||
|
|
margin: 0;
|
||
|
|
color: #6c757d;
|
||
|
|
font-style: italic;
|
||
|
|
font-size: 0.9em;
|
||
|
|
}
|
||
|
|
|
||
|
|
@keyframes loading {
|
||
|
|
0% {
|
||
|
|
opacity: 1;
|
||
|
|
}
|
||
|
|
50% {
|
||
|
|
opacity: 0.5;
|
||
|
|
}
|
||
|
|
100% {
|
||
|
|
opacity: 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.loading-spinner {
|
||
|
|
display: inline-block;
|
||
|
|
width: 16px;
|
||
|
|
height: 16px;
|
||
|
|
border: 2px solid #f3f3f3;
|
||
|
|
border-top: 2px solid #007bff;
|
||
|
|
border-radius: 50%;
|
||
|
|
animation: spin 1s linear infinite;
|
||
|
|
margin-right: 8px;
|
||
|
|
vertical-align: middle;
|
||
|
|
}
|
||
|
|
|
||
|
|
@keyframes spin {
|
||
|
|
0% { transform: rotate(0deg); }
|
||
|
|
100% { transform: rotate(360deg); }
|
||
|
|
}
|
||
|
|
|
||
|
|
.status.timeout {
|
||
|
|
background-color: #ffc107;
|
||
|
|
color: #000;
|
||
|
|
}
|
||
|
|
|
||
|
|
.status.error {
|
||
|
|
background-color: #dc3545;
|
||
|
|
color: white;
|
||
|
|
}
|
||
|
|
|
||
|
|
.text-warning {
|
||
|
|
color: #ffc107 !important;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.loading-container {
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.router-uptime {
|
||
|
|
color: #28a745; /* Green for uptime */
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.router-used-memory {
|
||
|
|
color: #fd7e14; /* Orange for memory */
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.router-cpu-load {
|
||
|
|
color: #d63384; /* Pink for CPU load */
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.router-status {
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.router-status .status {
|
||
|
|
display: inline-block;
|
||
|
|
padding: 2px 8px;
|
||
|
|
border-radius: 4px;
|
||
|
|
font-size: 12px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.router-status .online {
|
||
|
|
background-color: #28a745;
|
||
|
|
color: white;
|
||
|
|
}
|
||
|
|
|
||
|
|
.router-status .offline {
|
||
|
|
background-color: #dc3545;
|
||
|
|
color: white;
|
||
|
|
}
|
||
|
|
</style>
|
||
|
|
|
||
|
|
<?php echo '<script'; ?>
|
||
|
|
>
|
||
|
|
$(document).ready(function() {
|
||
|
|
// Get all router IDs
|
||
|
|
var routerIds = [];
|
||
|
|
$('.router-uptime, .router-used-memory, .router-total-memory, .router-cpu-load, .router-status').each(function() {
|
||
|
|
var routerId = $(this).data('router-id');
|
||
|
|
if (routerId && routerIds.indexOf(routerId) === -1) {
|
||
|
|
routerIds.push(routerId);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// Option 1: Load all router data in parallel with individual timeouts (current implementation)
|
||
|
|
var loadPromises = routerIds.map(function(routerId) {
|
||
|
|
return new Promise(function(resolve, reject) {
|
||
|
|
$.ajax({
|
||
|
|
url: '<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/get_resources',
|
||
|
|
data: { router_id: routerId },
|
||
|
|
dataType: 'json',
|
||
|
|
timeout: 8000, // 8 second timeout per router
|
||
|
|
success: function(resources) {
|
||
|
|
var result = {};
|
||
|
|
result.routerId = routerId;
|
||
|
|
result.resources = resources;
|
||
|
|
resolve(result);
|
||
|
|
},
|
||
|
|
error: function(xhr, status, error) {
|
||
|
|
var errorType = status === 'timeout' ? 'timeout' : 'error';
|
||
|
|
var result = {};
|
||
|
|
result.routerId = routerId;
|
||
|
|
result.error = errorType;
|
||
|
|
result.resources = null;
|
||
|
|
resolve(result);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// Process all results when they complete
|
||
|
|
Promise.all(loadPromises).then(function(results) {
|
||
|
|
results.forEach(function(result) {
|
||
|
|
var routerId = result.routerId;
|
||
|
|
var resources = result.resources;
|
||
|
|
var error = result.error;
|
||
|
|
|
||
|
|
// Find all elements for this router
|
||
|
|
var row = $('[data-router-id="' + routerId + '"]').first().closest('tr');
|
||
|
|
|
||
|
|
if (error) {
|
||
|
|
// Handle error state
|
||
|
|
row.find('.router-uptime').html('<span class="text-warning">' + (error === 'timeout' ? 'Timeout' : 'Error') + '</span>');
|
||
|
|
row.find('.router-used-memory').html('<span class="text-warning">' + (error === 'timeout' ? 'Timeout' : 'Error') + '</span>');
|
||
|
|
row.find('.router-cpu-load').html('<span class="text-warning">' + (error === 'timeout' ? 'Timeout' : 'Error') + '</span>');
|
||
|
|
row.find('.router-status').html('<span class="status offline">' + (error === 'timeout' ? 'Timeout' : 'Error') + '</span>');
|
||
|
|
} else if (resources) {
|
||
|
|
// Update all fields for this router
|
||
|
|
row.find('.router-uptime').html(resources.uptime || 'N/A');
|
||
|
|
row.find('.router-used-memory').html(resources.freeMemory || 'N/A');
|
||
|
|
row.find('.router-cpu-load').html(resources.cpuLoad || 'N/A');
|
||
|
|
|
||
|
|
// Update router status
|
||
|
|
var statusElement = row.find('.router-status');
|
||
|
|
if (resources.status === 'Online') {
|
||
|
|
statusElement.html('<span class="status online">Online</span>');
|
||
|
|
} else {
|
||
|
|
statusElement.html('<span class="status offline">Offline</span>');
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
// No data available
|
||
|
|
row.find('.router-uptime').html('N/A');
|
||
|
|
row.find('.router-used-memory').html('N/A');
|
||
|
|
row.find('.router-cpu-load').html('N/A');
|
||
|
|
row.find('.router-status').html('<span class="status offline">Offline</span>');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
// Option 2: Alternative bulk loading approach (commented out - uncomment to use)
|
||
|
|
/*
|
||
|
|
$.ajax({
|
||
|
|
url: '<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/get_all_resources',
|
||
|
|
dataType: 'json',
|
||
|
|
timeout: 15000, // 15 second timeout for bulk request
|
||
|
|
success: function(allResources) {
|
||
|
|
Object.keys(allResources).forEach(function(routerId) {
|
||
|
|
var resources = allResources[routerId];
|
||
|
|
var row = $('[data-router-id="' + routerId + '"]').first().closest('tr');
|
||
|
|
|
||
|
|
if (resources) {
|
||
|
|
row.find('.router-uptime').html(resources.uptime || 'N/A');
|
||
|
|
row.find('.router-used-memory').html(resources.freeMemory || 'N/A');
|
||
|
|
row.find('.router-cpu-load').html(resources.cpuLoad || 'N/A');
|
||
|
|
|
||
|
|
var statusElement = row.find('.router-status');
|
||
|
|
if (resources.status === 'Online') {
|
||
|
|
statusElement.html('<span class="status online">Online</span>');
|
||
|
|
} else {
|
||
|
|
statusElement.html('<span class="status offline">Offline</span>');
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
row.find('.router-uptime').html('N/A');
|
||
|
|
row.find('.router-used-memory').html('N/A');
|
||
|
|
row.find('.router-cpu-load').html('N/A');
|
||
|
|
row.find('.router-status').html('<span class="status offline">Offline</span>');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
},
|
||
|
|
error: function(xhr, status, error) {
|
||
|
|
console.error('Bulk loading failed:', error);
|
||
|
|
// Fallback to individual loading
|
||
|
|
$('.router-uptime, .router-used-memory, .router-cpu-load, .router-status').html('<span class="text-danger">Error</span>');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
*/
|
||
|
|
|
||
|
|
// Reboot router
|
||
|
|
$('.btn-reboot').on('click', function() {
|
||
|
|
var routerId = $(this).data('router-id');
|
||
|
|
if (confirm('Are you sure you want to reboot this router?')) {
|
||
|
|
$.ajax({
|
||
|
|
url: '<?php echo $_smarty_tpl->tpl_vars['_url']->value;?>
|
||
|
|
routers/reboot',
|
||
|
|
data: { router_id: routerId },
|
||
|
|
dataType: 'json',
|
||
|
|
success: function(response) {
|
||
|
|
if (response.status === 'Rebooting') {
|
||
|
|
alert(response.message);
|
||
|
|
} else {
|
||
|
|
alert('Error: ' + response.message);
|
||
|
|
}
|
||
|
|
},
|
||
|
|
error: function(xhr, status, error) {
|
||
|
|
console.error(xhr.responseText);
|
||
|
|
alert('Failed to send reboot command. Please try again.');
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|
||
|
|
<?php echo '</script'; ?>
|
||
|
|
><?php }
|
||
|
|
}
|