159 lines
5.8 KiB
HTML
159 lines
5.8 KiB
HTML
<html>
|
|
<head>
|
|
<title>Hero Agent UI - Processes</title>
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<h1>System Processes</h1>
|
|
<nav>
|
|
<a href="/">Dashboard</a>
|
|
<a href="/processes" class="active">Processes</a>
|
|
<a href="/jobs">Jobs</a>
|
|
<a href="/openrpc">OpenRPC</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<main>
|
|
<div class="processes-container">
|
|
<div class="filter-controls">
|
|
<input type="text" id="process-search" placeholder="Search processes..." onkeyup="filterProcesses()">
|
|
<div class="sort-controls">
|
|
<label>Sort by:</label>
|
|
<select id="sort-field" onchange="sortProcesses()">
|
|
<option value="pid">PID</option>
|
|
<option value="name">Name</option>
|
|
<option value="cpu">CPU Usage</option>
|
|
<option value="memory">Memory Usage</option>
|
|
</select>
|
|
<button id="sort-direction" onclick="toggleSortDirection()">↑</button>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="data-table" id="processes-table">
|
|
<thead>
|
|
<tr>
|
|
<th>PID</th>
|
|
<th>Name</th>
|
|
<th>CPU %</th>
|
|
<th>Memory (MB)</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for process in processes
|
|
<tr>
|
|
<td>@process.pid</td>
|
|
<td>@process.name</td>
|
|
<td>@process.cpu</td>
|
|
<td>@process.memory</td>
|
|
<td>
|
|
<a href="/processes/@process.pid" class="btn btn-small">Details</a>
|
|
<button onclick="killProcess('@process.pid')" class="btn btn-small btn-danger">Kill</button>
|
|
</td>
|
|
</tr>
|
|
@end
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</main>
|
|
|
|
<footer>
|
|
<p>© 2025 Hero Agent System</p>
|
|
</footer>
|
|
|
|
<script src="/static/js/main.js"></script>
|
|
<script>
|
|
function killProcess(pid) {
|
|
if (confirm('Are you sure you want to kill process ' + pid + '?')) {
|
|
fetch(`/api/processes/${pid}/kill`, { method: 'POST' })
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
alert('Process killed successfully');
|
|
location.reload();
|
|
} else {
|
|
alert('Failed to kill process');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function filterProcesses() {
|
|
const input = document.getElementById('process-search');
|
|
const filter = input.value.toUpperCase();
|
|
const table = document.getElementById('processes-table');
|
|
const rows = table.getElementsByTagName('tr');
|
|
|
|
for (let i = 1; i < rows.length; i++) {
|
|
const nameCell = rows[i].getElementsByTagName('td')[1];
|
|
if (nameCell) {
|
|
const nameValue = nameCell.textContent || nameCell.innerText;
|
|
if (nameValue.toUpperCase().indexOf(filter) > -1) {
|
|
rows[i].style.display = '';
|
|
} else {
|
|
rows[i].style.display = 'none';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let sortAscending = true;
|
|
|
|
function toggleSortDirection() {
|
|
sortAscending = !sortAscending;
|
|
const button = document.getElementById('sort-direction');
|
|
button.textContent = sortAscending ? '↑' : '↓';
|
|
sortProcesses();
|
|
}
|
|
|
|
function sortProcesses() {
|
|
const table = document.getElementById('processes-table');
|
|
const rows = Array.from(table.getElementsByTagName('tr')).slice(1);
|
|
const sortField = document.getElementById('sort-field').value;
|
|
|
|
let columnIndex;
|
|
let isNumeric = false;
|
|
|
|
switch (sortField) {
|
|
case 'pid':
|
|
columnIndex = 0;
|
|
isNumeric = true;
|
|
break;
|
|
case 'name':
|
|
columnIndex = 1;
|
|
break;
|
|
case 'cpu':
|
|
columnIndex = 2;
|
|
isNumeric = true;
|
|
break;
|
|
case 'memory':
|
|
columnIndex = 3;
|
|
isNumeric = true;
|
|
break;
|
|
default:
|
|
columnIndex = 0;
|
|
isNumeric = true;
|
|
}
|
|
|
|
rows.sort((a, b) => {
|
|
const aValue = a.getElementsByTagName('td')[columnIndex].textContent;
|
|
const bValue = b.getElementsByTagName('td')[columnIndex].textContent;
|
|
|
|
if (isNumeric) {
|
|
return sortAscending
|
|
? parseFloat(aValue) - parseFloat(bValue)
|
|
: parseFloat(bValue) - parseFloat(aValue);
|
|
} else {
|
|
return sortAscending
|
|
? aValue.localeCompare(bValue)
|
|
: bValue.localeCompare(aValue);
|
|
}
|
|
});
|
|
|
|
const tbody = table.getElementsByTagName('tbody')[0];
|
|
rows.forEach(row => tbody.appendChild(row));
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |