補 PPT AiderHeal 執行狀態
All checks were successful
CD Pipeline / deploy (push) Successful in 1m5s

This commit is contained in:
OoO
2026-05-19 00:49:06 +08:00
parent 83fd05d614
commit c08f76f315
7 changed files with 242 additions and 4 deletions

View File

@@ -73,6 +73,81 @@
font-weight: var(--momo-font-weight-bold, 700);
}
.ppt-aider-status {
display: grid;
grid-template-columns: minmax(260px, 0.36fr) minmax(0, 0.64fr);
gap: var(--momo-space-3, 12px);
align-items: stretch;
margin-top: var(--momo-space-3, 12px);
padding: var(--momo-space-3, 12px);
border: 1px solid rgba(184, 121, 47, 0.32);
border-radius: var(--momo-radius-lg, 8px);
background:
radial-gradient(circle, rgba(184, 121, 47, 0.1) 1px, transparent 1.2px),
rgba(255, 248, 239, 0.72);
background-size: 10px 10px, auto;
}
.ppt-aider-status.is-empty {
display: none;
}
.ppt-aider-status-main {
display: flex;
align-items: center;
gap: var(--momo-space-3, 12px);
}
.ppt-aider-status-main strong,
.ppt-aider-status-main small {
display: block;
}
.ppt-aider-status-main strong {
color: var(--obs-ink);
font-size: var(--momo-text-body, 14px);
font-weight: var(--momo-font-weight-black, 800);
}
.ppt-aider-status-main small {
color: var(--obs-muted);
}
.ppt-aider-job-list {
display: grid;
gap: var(--momo-space-2, 8px);
}
.ppt-aider-job {
display: grid;
grid-template-columns: minmax(180px, 0.42fr) minmax(130px, 0.22fr) minmax(0, 0.36fr);
gap: var(--momo-space-2, 8px);
align-items: center;
min-height: 42px;
padding: var(--momo-space-2, 8px);
border: 1px solid rgba(86, 64, 48, 0.12);
border-radius: var(--momo-radius-md, 6px);
background: rgba(255, 255, 255, 0.54);
}
.ppt-aider-job code,
.ppt-aider-job span,
.ppt-aider-job small {
min-width: 0;
overflow-wrap: anywhere;
}
.ppt-aider-job code {
color: var(--obs-ink);
font-family: var(--momo-font-mono);
}
.ppt-aider-job span,
.ppt-aider-job small {
color: var(--obs-muted);
font-size: var(--momo-text-caption, 12px);
}
.ppt-command {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
@@ -952,6 +1027,7 @@ body.ppt-preview-open {
}
.ppt-diagnostic-strip,
.ppt-aider-status,
.ppt-health-board,
.ppt-pipeline-layout {
grid-template-columns: 1fr;
@@ -1027,4 +1103,8 @@ body.ppt-preview-open {
.ppt-preview-frame-wrap iframe {
min-height: calc(100vh - 168px);
}
.ppt-aider-job {
grid-template-columns: 1fr;
}
}

View File

@@ -604,6 +604,9 @@
statusNode.classList.remove('is-working');
statusNode.textContent = data.message || 'AiderHeal 已排入背景執行,完成後會由 Telegram/Gitea/CD 結果回報。';
}
if (window.refreshPptAiderHealStatus) {
window.refreshPptAiderHealStatus();
}
} catch (error) {
console.warn('ppt_audit_trigger_aider_heal_failed', error);
if (triggerButton) {
@@ -617,6 +620,45 @@
}
};
function renderPptAiderHealStatus(payload) {
const panel = document.querySelector('[data-ppt-aider-status]');
if (!panel) return;
const jobs = Array.isArray(payload && payload.jobs) ? payload.jobs : [];
const count = Number((payload && payload.active_count) || jobs.length || 0);
panel.classList.toggle('is-empty', count <= 0);
const title = panel.querySelector('[data-ppt-aider-status-title]');
const meta = panel.querySelector('[data-ppt-aider-status-meta]');
const list = panel.querySelector('[data-ppt-aider-job-list]');
if (title) title.textContent = count > 0 ? `AiderHeal 執行中 · ${count}` : 'AiderHeal 待命';
if (meta) {
meta.textContent = count > 0
? '修復完成後會由 Telegram/Gitea/CD 回報。'
: '有問題的審核紀錄可直接一鍵派工。';
}
if (list) {
list.innerHTML = jobs.slice(0, 3).map(job => `
<div class="ppt-aider-job">
<code>${escapeHtml(job.pptx_filename || 'manual')}</code>
<span>${escapeHtml(job.queued_at || '')}</span>
<small>${escapeHtml(job.diagnosis || '')}</small>
</div>
`).join('');
}
}
window.refreshPptAiderHealStatus = async function refreshPptAiderHealStatus() {
try {
const response = await fetch('/observability/ppt_audit/aider_heal_status', {
headers: { 'Accept': 'application/json' }
});
const data = await response.json();
if (!response.ok || !data.ok) return;
renderPptAiderHealStatus(data);
} catch (error) {
console.warn('ppt_audit_aider_heal_status_failed', error);
}
};
function initPptAutoGeneration() {
const panel = document.querySelector('[data-ppt-auto-generation]');
const pageStatus = document.querySelector('[data-ppt-auto-status]');