diff --git a/static/app.css b/static/app.css index 6e120a8..8e22ea6 100644 --- a/static/app.css +++ b/static/app.css @@ -277,3 +277,57 @@ a { color: var(--accent); text-decoration: none; } .status-timeout { color: var(--warn); background: rgba(224, 164, 88, 0.12); } .status-skipped { color: var(--skipped); background: rgba(154, 163, 178, 0.12); } .status-running { color: var(--accent); background: rgba(91, 141, 239, 0.12); } + +/* ============ Running actions + Modal ============ */ +.running-actions { margin-top: 12px; display: flex; gap: 8px; } + +.modal { + position: fixed; + inset: 0; + z-index: 100; + display: flex; + align-items: center; + justify-content: center; +} +.modal[hidden] { display: none; } +.modal-backdrop { + position: absolute; + inset: 0; + background: rgba(0, 0, 0, 0.6); +} +.modal-dialog { + position: relative; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 12px; + box-shadow: var(--shadow); + width: min(900px, 92vw); + height: min(72vh, 720px); + display: flex; + flex-direction: column; + overflow: hidden; +} +.modal-head { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 16px; + border-bottom: 1px solid var(--border); + background: var(--surface-2); +} +.modal-head h3 { margin: 0; font-size: 14px; font-weight: 600; color: var(--text); } +.modal-log { + flex: 1; + height: auto; + border: none; + border-radius: 0; +} +.modal-foot { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 16px; + border-top: 1px solid var(--border); + background: var(--surface-2); + font-size: 12px; +} diff --git a/static/app.js b/static/app.js index a6e2791..c879999 100644 --- a/static/app.js +++ b/static/app.js @@ -15,6 +15,7 @@ const state = { autoscroll: true, expandedLogs: new Set(), // 已展开的历史日志 record ID(re-render 后恢复) lastLiveKey: null, // 上次渲染的"当前任务身份"(用于判断是否需要重建 DOM) + modalOpen: false, // 实时日志弹窗是否打开 }; // ============ Helpers ============ @@ -67,6 +68,7 @@ async function pollQueue() { setConn(true, "已连接"); renderQueue(); renderRunning(); + if (state.modalOpen) refreshModalLog(); } catch (e) { setConn(false, "连接失败"); console.warn("queue poll failed:", e); @@ -114,13 +116,11 @@ function renderQueue() { function renderRunning() { const body = $("#running-body"); const stateBadge = $("#running-state"); - const sizeEl = $("#log-size"); if (!state.current) { stateBadge.textContent = "空闲"; stateBadge.className = "badge badge-grey"; body.innerHTML = `
当前没有任务在执行
`; - sizeEl.textContent = ""; state.lastLiveKey = null; return; } @@ -130,38 +130,48 @@ function renderRunning() { stateBadge.className = "badge badge-warn"; const liveKey = `${c.task.script}|${c.task.repo}|${c.task.ref}|${c.startedAt}`; - // 仅渲染尾部以避免长日志卡顿 - const fullLog = c.log || ""; + if (state.lastLiveKey === liveKey) return; + state.lastLiveKey = liveKey; + + body.innerHTML = ` + +当前没有任务在执行
(等待脚本输出…)+ +