feat: implement dashboard pagination
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -117,6 +117,7 @@
|
||||
<tbody id="jobTableBody">
|
||||
</tbody>
|
||||
</table>
|
||||
<div id="paginationControls" class="mt-3"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -307,10 +308,21 @@
|
||||
setInterval(checkStatus, 5000);
|
||||
checkStatus();
|
||||
|
||||
async function loadJobs() {
|
||||
|
||||
// Pagination state
|
||||
let currentPage = 1;
|
||||
let limit = 10;
|
||||
|
||||
async function loadJobs(page = 1) {
|
||||
try {
|
||||
const res = await fetch('/api/jobs');
|
||||
const jobs = await res.json();
|
||||
const res = await fetch(`/api/jobs?page=${page}&limit=${limit}`);
|
||||
const data = await res.json();
|
||||
|
||||
// Handle both legacy (array) and new (object) format gracefully
|
||||
const jobs = Array.isArray(data) ? data : (data.jobs || []);
|
||||
const totalPages = data.total_pages || 1;
|
||||
currentPage = data.page || 1;
|
||||
|
||||
const tbody = document.getElementById('jobTableBody');
|
||||
tbody.innerHTML = '';
|
||||
|
||||
@@ -319,6 +331,8 @@
|
||||
if(job.status === 'completed') badgeClass = 'success';
|
||||
else if(job.status === 'processing' || job.status === 'calling') badgeClass = 'warning';
|
||||
else if(job.status === 'failed') badgeClass = 'danger';
|
||||
else if(job.status === 'rejected') badgeClass = 'dark';
|
||||
else if(job.status === 'no_answer') badgeClass = 'warning text-dark';
|
||||
|
||||
let statusHtml = `<span class="badge bg-${badgeClass}">${job.status}</span>`;
|
||||
|
||||
@@ -357,13 +371,40 @@
|
||||
tbody.appendChild(tr);
|
||||
});
|
||||
|
||||
renderPagination(currentPage, totalPages);
|
||||
|
||||
} catch(e) {
|
||||
console.error("Failed to load jobs", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Poll every 2 seconds
|
||||
setInterval(loadJobs, 2000);
|
||||
function renderPagination(current, total) {
|
||||
const container = document.getElementById('paginationControls');
|
||||
if (!container) return; // Should be added to HTML
|
||||
|
||||
container.innerHTML = `
|
||||
<nav aria-label="Page navigation">
|
||||
<ul class="pagination justify-content-center">
|
||||
<li class="page-item ${current <= 1 ? 'disabled' : ''}">
|
||||
<button class="page-link" onclick="changePage(${current - 1})">Previous</button>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<span class="page-link">Page ${current} of ${Math.max(1, total)}</span>
|
||||
</li>
|
||||
<li class="page-item ${current >= total ? 'disabled' : ''}">
|
||||
<button class="page-link" onclick="changePage(${current + 1})">Next</button>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
`;
|
||||
}
|
||||
|
||||
function changePage(newPage) {
|
||||
loadJobs(newPage);
|
||||
}
|
||||
|
||||
// Poll every 5 seconds (slower poll for pagination)
|
||||
setInterval(() => loadJobs(currentPage), 5000);
|
||||
loadJobs();
|
||||
|
||||
document.getElementById('testVoiceBtn').addEventListener('click', async () => {
|
||||
|
||||
@@ -42,12 +42,18 @@ if ($method === 'POST' && $uri === '/api/queue') {
|
||||
exit;
|
||||
}
|
||||
|
||||
// API: Jobs History
|
||||
// API: Jobs History (Paginated)
|
||||
if ($method === 'GET' && $uri === '/api/jobs') {
|
||||
// Get last 50 jobs
|
||||
$ids = $redis->lrange('job_history', 0, 49);
|
||||
$jobs = [];
|
||||
$page = isset($_GET['page']) ? max(1, (int)$_GET['page']) : 1;
|
||||
$limit = isset($_GET['limit']) ? max(1, min(100, (int)$_GET['limit'])) : 20;
|
||||
|
||||
$start = ($page - 1) * $limit;
|
||||
$end = $start + $limit - 1;
|
||||
|
||||
$total = $redis->llen('job_history');
|
||||
$ids = $redis->lrange('job_history', $start, $end);
|
||||
|
||||
$jobs = [];
|
||||
foreach ($ids as $id) {
|
||||
$job = $redis->hgetall("job:$id");
|
||||
if ($job) {
|
||||
@@ -55,7 +61,13 @@ if ($method === 'GET' && $uri === '/api/jobs') {
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($jobs);
|
||||
echo json_encode([
|
||||
'jobs' => $jobs,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit,
|
||||
'total_pages' => ceil($total / $limit)
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user