fix: 修复任务页面过滤的问题

This commit is contained in:
2026-06-19 18:01:20 +08:00
parent 73dfe12c95
commit 14cd626b0d
2 changed files with 52 additions and 22 deletions
+6
View File
@@ -80,6 +80,12 @@ export function getJobMeta(jobid) {
return state.jobMeta.get(Number(jobid)); return state.jobMeta.get(Number(jobid));
} }
export function listJobMeta() {
return Array.from(state.jobMeta.entries())
.map(([jobid, meta]) => ({ jobid: Number(jobid), ...meta }))
.sort((a, b) => b.jobid - a.jobid);
}
export function forgetJob(jobid) { export function forgetJob(jobid) {
state.jobMeta.delete(Number(jobid)); state.jobMeta.delete(Number(jobid));
saveJobMeta(); saveJobMeta();
+42 -18
View File
@@ -7,6 +7,8 @@ import {
toast, toast,
rememberJob, rememberJob,
getJobMeta, getJobMeta,
listJobMeta,
forgetJob,
formatBytes, formatBytes,
formatSpeed, formatSpeed,
formatDuration, formatDuration,
@@ -14,6 +16,7 @@ import {
import { t } from "../i18n.js"; import { t } from "../i18n.js";
let pollTimer = null; let pollTimer = null;
const WEBGUI_JOB_GROUP_PREFIX = "webgui/transfer";
export async function renderJobs() { export async function renderJobs() {
const app = document.getElementById("app"); const app = document.getElementById("app");
@@ -30,8 +33,12 @@ export async function renderJobs() {
</div> </div>
`; `;
await refreshJobs(); const hasRunning = await refreshJobs();
if (hasRunning) {
startPolling(); startPolling();
} else {
stopPolling();
}
} }
export async function renderNewJob() { export async function renderNewJob() {
@@ -114,7 +121,11 @@ export async function renderNewJob() {
const src = srcPath ? `${srcRemote}${srcPath}` : srcRemote; const src = srcPath ? `${srcRemote}${srcPath}` : srcRemote;
const dst = dstPath ? `${dstRemote}${dstPath}` : dstRemote; const dst = dstPath ? `${dstRemote}${dstPath}` : dstRemote;
try { try {
const body = { srcFs: src, dstFs: dst }; const body = {
srcFs: src,
dstFs: dst,
_group: `${WEBGUI_JOB_GROUP_PREFIX}/${action}`,
};
if (action === "move") body.deleteEmptySrcDirs = true; if (action === "move") body.deleteEmptySrcDirs = true;
const res = await postAsync(`sync/${action}`, body); const res = await postAsync(`sync/${action}`, body);
const jobid = res && res.jobid; const jobid = res && res.jobid;
@@ -131,18 +142,10 @@ export async function renderNewJob() {
async function refreshJobs() { async function refreshJobs() {
const card = document.getElementById("jobs-card"); const card = document.getElementById("jobs-card");
if (!card) return; if (!card) return false;
let jobIds = []; const trackedJobs = listJobMeta();
try { const jobIds = trackedJobs.map((job) => job.jobid);
const list = await post("job/list");
const running = (list && list.jobids) || [];
const finished = (list && list.finishedIds) || [];
jobIds = [...new Set([...running, ...finished])];
} catch (e) {
card.innerHTML = `<div class="empty"><h3>${t("error.couldnt_load_jobs")}</h3><p>${escapeHtml(e.message)}</p></div>`;
return;
}
if (jobIds.length === 0) { if (jobIds.length === 0) {
card.innerHTML = ` card.innerHTML = `
@@ -151,23 +154,41 @@ async function refreshJobs() {
<p>${t("jobs.empty_body").replace("New Job", `<a href="#/jobs/new">${t("jobs.new_btn")}</a>`)}</p> <p>${t("jobs.empty_body").replace("New Job", `<a href="#/jobs/new">${t("jobs.new_btn")}</a>`)}</p>
</div> </div>
`; `;
return; return false;
} }
const statuses = await Promise.all( const statuses = await Promise.all(
jobIds.map((id) => jobIds.map((id) =>
post("job/status", { jobid: id }).catch((e) => ({ post("job/status", { jobid: id }).catch((e) => {
if (e.message.includes("job not found")) {
forgetJob(id);
return null;
}
return {
jobid: id, jobid: id,
error: e.message, error: e.message,
finished: true, finished: true,
})), };
}),
), ),
); );
card.innerHTML = renderJobTable(statuses); const tracked = statuses.filter(Boolean);
if (tracked.length === 0) {
card.innerHTML = `
<div class="empty">
<h3>${t("jobs.empty_title")}</h3>
<p>${t("jobs.empty_body").replace("New Job", `<a href="#/jobs/new">${t("jobs.new_btn")}</a>`)}</p>
</div>
`;
return false;
}
card.innerHTML = renderJobTable(tracked);
card.querySelectorAll("[data-stop]").forEach((btn) => { card.querySelectorAll("[data-stop]").forEach((btn) => {
btn.addEventListener("click", () => onStop(parseInt(btn.dataset.stop, 10))); btn.addEventListener("click", () => onStop(parseInt(btn.dataset.stop, 10)));
}); });
return tracked.some((status) => !status.finished);
} }
function renderJobTable(statuses) { function renderJobTable(statuses) {
@@ -275,7 +296,10 @@ function startPolling() {
stopPolling(); stopPolling();
return; return;
} }
await refreshJobs(); const hasRunning = await refreshJobs();
if (!hasRunning) {
stopPolling();
}
}, 1500); }, 1500);
} }