fix bugs
This commit is contained in:
+58
-13
@@ -13,6 +13,8 @@ const state = {
|
|||||||
history: {}, // { scriptPath: [record, ...] }
|
history: {}, // { scriptPath: [record, ...] }
|
||||||
scripts: [], // 配置中的全部脚本
|
scripts: [], // 配置中的全部脚本
|
||||||
autoscroll: true,
|
autoscroll: true,
|
||||||
|
expandedLogs: new Set(), // 已展开的历史日志 record ID(re-render 后恢复)
|
||||||
|
lastLiveKey: null, // 上次渲染的"当前任务身份"(用于判断是否需要重建 DOM)
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============ Helpers ============
|
// ============ Helpers ============
|
||||||
@@ -119,6 +121,7 @@ function renderRunning() {
|
|||||||
stateBadge.className = "badge badge-grey";
|
stateBadge.className = "badge badge-grey";
|
||||||
body.innerHTML = `<p class="empty">当前没有任务在执行</p>`;
|
body.innerHTML = `<p class="empty">当前没有任务在执行</p>`;
|
||||||
sizeEl.textContent = "";
|
sizeEl.textContent = "";
|
||||||
|
state.lastLiveKey = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,6 +129,15 @@ function renderRunning() {
|
|||||||
stateBadge.textContent = "执行中";
|
stateBadge.textContent = "执行中";
|
||||||
stateBadge.className = "badge badge-warn";
|
stateBadge.className = "badge badge-warn";
|
||||||
|
|
||||||
|
const liveKey = `${c.task.script}|${c.task.repo}|${c.task.ref}|${c.startedAt}`;
|
||||||
|
// 仅渲染尾部以避免长日志卡顿
|
||||||
|
const fullLog = c.log || "";
|
||||||
|
const tail = fullLog.length > LOG_TAIL_CHARS
|
||||||
|
? fullLog.slice(fullLog.length - LOG_TAIL_CHARS)
|
||||||
|
: fullLog;
|
||||||
|
|
||||||
|
if (state.lastLiveKey !== liveKey) {
|
||||||
|
// 任务身份变化:重建结构并贴底
|
||||||
body.innerHTML = `
|
body.innerHTML = `
|
||||||
<dl class="running-meta">
|
<dl class="running-meta">
|
||||||
<dt>仓库</dt><dd>${escapeHtml(c.task.repo)}</dd>
|
<dt>仓库</dt><dd>${escapeHtml(c.task.repo)}</dd>
|
||||||
@@ -136,20 +148,30 @@ function renderRunning() {
|
|||||||
</dl>
|
</dl>
|
||||||
<pre class="log-box" id="live-log"></pre>
|
<pre class="log-box" id="live-log"></pre>
|
||||||
`;
|
`;
|
||||||
|
state.lastLiveKey = liveKey;
|
||||||
const logBox = $("#live-log");
|
const logBox = $("#live-log");
|
||||||
// 仅渲染尾部以避免长日志卡顿
|
|
||||||
const fullLog = c.log || "";
|
|
||||||
const tail = fullLog.length > LOG_TAIL_CHARS
|
|
||||||
? fullLog.slice(fullLog.length - LOG_TAIL_CHARS)
|
|
||||||
: fullLog;
|
|
||||||
logBox.textContent = tail || "(等待脚本输出…)";
|
logBox.textContent = tail || "(等待脚本输出…)";
|
||||||
sizeEl.textContent = fullLog.length
|
sizeEl.textContent = fullLog.length
|
||||||
? `${(fullLog.length / 1024).toFixed(1)} KB`
|
? `${(fullLog.length / 1024).toFixed(1)} KB`
|
||||||
: "";
|
: "";
|
||||||
|
requestAnimationFrame(() => {
|
||||||
if (state.autoscroll) {
|
|
||||||
logBox.scrollTop = logBox.scrollHeight;
|
logBox.scrollTop = logBox.scrollHeight;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同一任务:仅更新日志内容,保持 DOM 节点稳定
|
||||||
|
const logBox = $("#live-log");
|
||||||
|
const distanceFromBottom = logBox.scrollHeight - logBox.scrollTop - logBox.clientHeight;
|
||||||
|
const atBottom = distanceFromBottom <= 24;
|
||||||
|
logBox.textContent = tail || "(等待脚本输出…)";
|
||||||
|
sizeEl.textContent = fullLog.length
|
||||||
|
? `${(fullLog.length / 1024).toFixed(1)} KB`
|
||||||
|
: "";
|
||||||
|
if (state.autoscroll && atBottom) {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
logBox.scrollTop = logBox.scrollHeight;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,7 +217,7 @@ function renderHistory() {
|
|||||||
<td>${escapeHtml(r.reason || "")}</td>
|
<td>${escapeHtml(r.reason || "")}</td>
|
||||||
<td>
|
<td>
|
||||||
${r.log
|
${r.log
|
||||||
? `<button class="toggle-log" data-target="${logId}" type="button">查看日志</button>`
|
? `<button class="toggle-log" data-target="${logId}" data-id="${r.id}" type="button">查看日志</button>`
|
||||||
: `<span class="muted small">无日志</span>`}
|
: `<span class="muted small">无日志</span>`}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -225,14 +247,29 @@ function renderHistory() {
|
|||||||
`;
|
`;
|
||||||
}).join("");
|
}).join("");
|
||||||
|
|
||||||
// 绑定展开日志按钮
|
// 恢复展开状态(re-render 后保持已展开的日志)
|
||||||
|
root.querySelectorAll(".toggle-log").forEach((btn) => {
|
||||||
|
const expanded = state.expandedLogs.has(btn.dataset.id);
|
||||||
|
btn.textContent = expanded ? "收起日志" : "查看日志";
|
||||||
|
const t = document.getElementById(btn.dataset.target);
|
||||||
|
if (t) t.style.display = expanded ? "block" : "none";
|
||||||
|
});
|
||||||
|
|
||||||
|
// 绑定展开日志按钮(以 state.expandedLogs 为单一事实源)
|
||||||
root.querySelectorAll(".toggle-log").forEach((btn) => {
|
root.querySelectorAll(".toggle-log").forEach((btn) => {
|
||||||
btn.addEventListener("click", () => {
|
btn.addEventListener("click", () => {
|
||||||
const target = document.getElementById(btn.dataset.target);
|
const target = document.getElementById(btn.dataset.target);
|
||||||
if (!target) return;
|
if (!target) return;
|
||||||
const visible = target.style.display !== "none";
|
const id = btn.dataset.id;
|
||||||
target.style.display = visible ? "none" : "block";
|
if (state.expandedLogs.has(id)) {
|
||||||
btn.textContent = visible ? "查看日志" : "收起日志";
|
state.expandedLogs.delete(id);
|
||||||
|
target.style.display = "none";
|
||||||
|
btn.textContent = "查看日志";
|
||||||
|
} else {
|
||||||
|
state.expandedLogs.add(id);
|
||||||
|
target.style.display = "block";
|
||||||
|
btn.textContent = "收起日志";
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -246,6 +283,14 @@ $("#refresh-btn").addEventListener("click", () => {
|
|||||||
$("#log-autoscroll").addEventListener("click", (e) => {
|
$("#log-autoscroll").addEventListener("click", (e) => {
|
||||||
state.autoscroll = !state.autoscroll;
|
state.autoscroll = !state.autoscroll;
|
||||||
e.currentTarget.classList.toggle("active", state.autoscroll);
|
e.currentTarget.classList.toggle("active", state.autoscroll);
|
||||||
|
if (state.autoscroll) {
|
||||||
|
const logBox = $("#live-log");
|
||||||
|
if (logBox) {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
logBox.scrollTop = logBox.scrollHeight;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
pollQueue();
|
pollQueue();
|
||||||
|
|||||||
Reference in New Issue
Block a user