117 lines
4.7 KiB
HTML
117 lines
4.7 KiB
HTML
<html>
|
|
<head>
|
|
<title>Hero Agent UI - Jobs</title>
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<h1>Job Management</h1>
|
|
<nav>
|
|
<a href="/">Dashboard</a>
|
|
<a href="/processes">Processes</a>
|
|
<a href="/jobs" class="active">Jobs</a>
|
|
<a href="/openrpc">OpenRPC</a>
|
|
</nav>
|
|
</header>
|
|
|
|
<main>
|
|
<div class="jobs-container">
|
|
<div class="filter-controls">
|
|
<input type="text" id="job-search" placeholder="Search jobs..." onkeyup="filterJobs()">
|
|
<div class="filter-buttons">
|
|
<button class="filter-btn active" data-status="all" onclick="filterByStatus('all')">All</button>
|
|
<button class="filter-btn" data-status="new" onclick="filterByStatus('new')">New</button>
|
|
<button class="filter-btn" data-status="active" onclick="filterByStatus('active')">Active</button>
|
|
<button class="filter-btn" data-status="done" onclick="filterByStatus('done')">Done</button>
|
|
<button class="filter-btn" data-status="error" onclick="filterByStatus('error')">Error</button>
|
|
</div>
|
|
</div>
|
|
|
|
<table class="data-table" id="jobs-table">
|
|
<thead>
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Circle</th>
|
|
<th>Topic</th>
|
|
<th>Status</th>
|
|
<th>Scheduled</th>
|
|
<th>Duration</th>
|
|
<th>Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@for job in jobs
|
|
<tr class="status-@job.status" data-status="@job.status">
|
|
<td>@job.job_id</td>
|
|
<td>@job.circle_id</td>
|
|
<td>@job.topic</td>
|
|
<td>@job.status</td>
|
|
<td>@job.time_scheduled</td>
|
|
<td>@job.duration</td>
|
|
<td>
|
|
<a href="/jobs/@job.job_id" class="btn btn-small">Details</a>
|
|
</td>
|
|
</tr>
|
|
@end
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</main>
|
|
|
|
<footer>
|
|
<p>© 2025 Hero Agent System</p>
|
|
</footer>
|
|
|
|
<script src="/static/js/main.js"></script>
|
|
<script>
|
|
function filterJobs() {
|
|
const input = document.getElementById('job-search');
|
|
const filter = input.value.toUpperCase();
|
|
const table = document.getElementById('jobs-table');
|
|
const rows = table.getElementsByTagName('tr');
|
|
const activeStatus = document.querySelector('.filter-btn.active').dataset.status;
|
|
|
|
for (let i = 1; i < rows.length; i++) {
|
|
const topicCell = rows[i].getElementsByTagName('td')[2];
|
|
const circleCell = rows[i].getElementsByTagName('td')[1];
|
|
const statusMatch = activeStatus === 'all' || rows[i].dataset.status === activeStatus;
|
|
|
|
if (topicCell && circleCell) {
|
|
const topicValue = topicCell.textContent || topicCell.innerText;
|
|
const circleValue = circleCell.textContent || circleCell.innerText;
|
|
const textMatch = topicValue.toUpperCase().indexOf(filter) > -1 ||
|
|
circleValue.toUpperCase().indexOf(filter) > -1;
|
|
|
|
if (textMatch && statusMatch) {
|
|
rows[i].style.display = '';
|
|
} else {
|
|
rows[i].style.display = 'none';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function filterByStatus(status) {
|
|
// Update active button
|
|
document.querySelectorAll('.filter-btn').forEach(btn => {
|
|
btn.classList.remove('active');
|
|
});
|
|
document.querySelector(`.filter-btn[data-status="${status}"]`).classList.add('active');
|
|
|
|
// Filter table
|
|
const table = document.getElementById('jobs-table');
|
|
const rows = table.getElementsByTagName('tr');
|
|
|
|
for (let i = 1; i < rows.length; i++) {
|
|
if (status === 'all') {
|
|
rows[i].style.display = '';
|
|
} else if (rows[i].dataset.status === status) {
|
|
rows[i].style.display = '';
|
|
} else {
|
|
rows[i].style.display = 'none';
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |