- 移除 Diff 视图中的「🤖 AI 评审」按钮及行内进度/总结区域
- Review Tab 的「开始审查」现在具备行内 Diff 建议插入能力
- 合并 startInlineReview 到 startReview,统一 SSE 流和变量
- 移除独立的 review-diff-container,建议直接插入 Diff Tab 的 diff 视图
- 完成后 Review Tab 显示总结/备注/卡片,Diff Tab 显示行内建议
This commit is contained in:
+72
-205
@@ -51,9 +51,9 @@
|
|||||||
border: 1px solid #fde68a;
|
border: 1px solid #fde68a;
|
||||||
}
|
}
|
||||||
@media print {
|
@media print {
|
||||||
nav, footer, #review-actions, #btn-review, #btn-toggle-diff,
|
nav, footer, #review-actions, #btn-review,
|
||||||
.note-save-indicator, select, input, #review-progress,
|
.note-save-indicator, select, input, #review-progress,
|
||||||
#diff-review-container, #history-select,
|
#history-select,
|
||||||
label[for="base-ref"], label[for="head-ref"],
|
label[for="base-ref"], label[for="head-ref"],
|
||||||
label[for="top-n"], label[for="concurrency"] { display: none !important; }
|
label[for="top-n"], label[for="concurrency"] { display: none !important; }
|
||||||
|
|
||||||
@@ -139,9 +139,6 @@
|
|||||||
<div class="flex gap-1 ml-auto items-center">
|
<div class="flex gap-1 ml-auto items-center">
|
||||||
<button onclick="setDiffView('side-by-side')" id="btn-side-by-side" class="px-3 py-1 text-xs bg-blue-100 text-blue-700 rounded font-medium">并排</button>
|
<button onclick="setDiffView('side-by-side')" id="btn-side-by-side" class="px-3 py-1 text-xs bg-blue-100 text-blue-700 rounded font-medium">并排</button>
|
||||||
<button onclick="setDiffView('unified')" id="btn-unified" class="px-3 py-1 text-xs bg-gray-100 text-gray-600 rounded hover:bg-gray-200">统一</button>
|
<button onclick="setDiffView('unified')" id="btn-unified" class="px-3 py-1 text-xs bg-gray-100 text-gray-600 rounded hover:bg-gray-200">统一</button>
|
||||||
<button onclick="startInlineReview()" id="btn-inline-review" class="px-3 py-1 text-xs bg-purple-100 text-purple-700 rounded font-medium hover:bg-purple-200 ml-2">
|
|
||||||
🤖 AI 评审
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-2 flex items-center gap-3">
|
<div class="mt-2 flex items-center gap-3">
|
||||||
@@ -183,28 +180,6 @@
|
|||||||
<!-- Diff Tab -->
|
<!-- Diff Tab -->
|
||||||
<div id="panel-diff" class="p-4 hidden">
|
<div id="panel-diff" class="p-4 hidden">
|
||||||
<div id="diff-container"></div>
|
<div id="diff-container"></div>
|
||||||
<!-- Inline review progress -->
|
|
||||||
<div id="review-progress" class="hidden mt-4 bg-white rounded-lg border p-4">
|
|
||||||
<div class="flex items-center justify-between mb-2">
|
|
||||||
<span class="text-sm font-medium text-gray-700">🤖 AI 代码审查</span>
|
|
||||||
<button onclick="cancelInlineReview()" class="text-xs text-gray-400 hover:text-gray-600">取消</button>
|
|
||||||
</div>
|
|
||||||
<div class="w-full bg-gray-200 rounded-full h-2 mb-2">
|
|
||||||
<div id="review-progress-bar" class="bg-purple-600 h-2 rounded-full transition-all duration-300" style="width: 0%"></div>
|
|
||||||
</div>
|
|
||||||
<p id="review-progress-text" class="text-xs text-gray-500">准备中...</p>
|
|
||||||
</div>
|
|
||||||
<!-- Review summary (shown after completion) -->
|
|
||||||
<div id="review-summary" class="hidden mt-4 bg-white rounded-lg border p-4">
|
|
||||||
<div class="flex items-center justify-between mb-2">
|
|
||||||
<span class="text-sm font-medium text-gray-700">审查总结</span>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button onclick="showTab('review'); startReview()" class="text-xs text-purple-600 hover:underline">查看完整审查</button>
|
|
||||||
<button onclick="clearInlineReview()" class="text-xs text-gray-400 hover:text-gray-600">清除</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="review-summary-content" class="text-sm text-gray-700"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- PR Description Tab -->
|
<!-- PR Description Tab -->
|
||||||
@@ -275,12 +250,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Progress -->
|
<!-- Progress -->
|
||||||
<div id="review-progress-full" class="mb-6 hidden">
|
<div id="review-progress" class="mb-6 hidden">
|
||||||
<h3 class="font-semibold text-gray-700 mb-2">审查进度</h3>
|
<div class="flex items-center justify-between mb-2">
|
||||||
<div class="w-full bg-gray-200 rounded-full h-2.5 mb-2">
|
<h3 class="font-semibold text-gray-700">🤖 审查进度</h3>
|
||||||
<div id="review-progress-bar-full" class="bg-purple-600 h-2.5 rounded-full transition-all duration-300" style="width: 0%"></div>
|
<button onclick="cancelReview()" class="text-xs text-gray-400 hover:text-gray-600">取消</button>
|
||||||
</div>
|
</div>
|
||||||
<p id="review-progress-text-full" class="text-sm text-gray-500">准备中...</p>
|
<div class="w-full bg-gray-200 rounded-full h-2.5 mb-2">
|
||||||
|
<div id="review-progress-bar" class="bg-purple-600 h-2.5 rounded-full transition-all duration-300" style="width: 0%"></div>
|
||||||
|
</div>
|
||||||
|
<p id="review-progress-text" class="text-sm text-gray-500">准备中...</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Results -->
|
<!-- Results -->
|
||||||
@@ -316,27 +294,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Actions Bar -->
|
<!-- Actions Bar -->
|
||||||
<div id="review-actions" class="flex items-center gap-3 mb-6 hidden">
|
<div id="review-actions" class="flex items-center gap-3 mb-6">
|
||||||
<button onclick="NoteEditor.exportPDF()" id="btn-export-pdf"
|
<button onclick="NoteEditor.exportPDF()" id="btn-export-pdf"
|
||||||
class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 text-sm">
|
class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 text-sm">
|
||||||
📄 导出 PDF 报告
|
📄 导出 PDF 报告
|
||||||
</button>
|
</button>
|
||||||
|
<button onclick="showTab('diff')" class="text-sm text-purple-600 hover:underline">
|
||||||
|
查看 Diff 中的行内建议 →
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Inline Diff + Suggestions View -->
|
<!-- File Reviews -->
|
||||||
<div id="diff-review-container" class="mb-6">
|
|
||||||
<div class="flex items-center justify-between mb-3">
|
|
||||||
<h2 class="text-lg font-semibold text-gray-900">代码变更 & 审查建议</h2>
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button onclick="toggleDiffView()" id="btn-toggle-diff" class="px-3 py-1 text-xs bg-gray-100 rounded hover:bg-gray-200">
|
|
||||||
隐藏 Diff
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="review-diff-container"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- File Reviews (card-based fallback) -->
|
|
||||||
<div id="file-reviews" class="space-y-4"></div>
|
<div id="file-reviews" class="space-y-4"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -626,109 +594,15 @@
|
|||||||
return Markdown.render(text);
|
return Markdown.render(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Inline AI Review (quick review in Diff tab) ─────────────────
|
// ── Insert suggestions into Diff tab's diff view ──────────────
|
||||||
|
|
||||||
let inlineReviewSSE = null;
|
|
||||||
let inlineSuggestions = [];
|
|
||||||
|
|
||||||
function startInlineReview() {
|
|
||||||
const base = document.getElementById('select-base').value;
|
|
||||||
const head = document.getElementById('select-head').value;
|
|
||||||
if (!base || !head) {
|
|
||||||
showToast('请先选择 Base 和 Head 并查看 Diff', 'warning');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel previous if running
|
|
||||||
if (inlineReviewSSE) {
|
|
||||||
inlineReviewSSE.abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
const btn = document.getElementById('btn-inline-review');
|
|
||||||
const progress = document.getElementById('review-progress');
|
|
||||||
const summary = document.getElementById('review-summary');
|
|
||||||
|
|
||||||
btn.disabled = true;
|
|
||||||
btn.textContent = '⏳ 审查中...';
|
|
||||||
progress.classList.remove('hidden');
|
|
||||||
summary.classList.add('hidden');
|
|
||||||
|
|
||||||
inlineSuggestions = [];
|
|
||||||
let totalFiles = 0;
|
|
||||||
let completedFiles = 0;
|
|
||||||
|
|
||||||
inlineReviewSSE = SSE.post(`/api/repos/${repoId}/review`, {
|
|
||||||
base, head, top_n: 0,
|
|
||||||
}, {
|
|
||||||
start(data) {
|
|
||||||
totalFiles = data.total_files || 0;
|
|
||||||
document.getElementById('review-progress-text').textContent = `准备审查 ${totalFiles} 个文件...`;
|
|
||||||
document.getElementById('review-progress-bar').style.width = '5%';
|
|
||||||
},
|
|
||||||
file_start(data) {
|
|
||||||
completedFiles++;
|
|
||||||
const pct = totalFiles > 0 ? Math.round((completedFiles / totalFiles) * 80 + 10) : 50;
|
|
||||||
document.getElementById('review-progress-bar').style.width = pct + '%';
|
|
||||||
document.getElementById('review-progress-text').textContent = `正在审查: ${data.file || ''} (${completedFiles}/${totalFiles})`;
|
|
||||||
},
|
|
||||||
suggestion(data) {
|
|
||||||
inlineSuggestions.push(data);
|
|
||||||
},
|
|
||||||
summary(data) {
|
|
||||||
const el = document.getElementById('review-summary-content');
|
|
||||||
if (data.score !== undefined) {
|
|
||||||
el.innerHTML = renderSummaryHtml(data);
|
|
||||||
} else {
|
|
||||||
el.innerHTML = renderMarkdown(data.content || '');
|
|
||||||
}
|
|
||||||
document.getElementById('review-progress-bar').style.width = '90%';
|
|
||||||
},
|
|
||||||
done() {
|
|
||||||
document.getElementById('review-progress-bar').style.width = '100%';
|
|
||||||
document.getElementById('review-progress-text').textContent = '审查完成!';
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
progress.classList.add('hidden');
|
|
||||||
summary.classList.remove('hidden');
|
|
||||||
btn.disabled = false;
|
|
||||||
btn.textContent = '🤖 AI 评审';
|
|
||||||
}, 500);
|
|
||||||
|
|
||||||
// Insert suggestions into the existing diff
|
|
||||||
insertInlineSuggestions();
|
|
||||||
inlineReviewSSE = null;
|
|
||||||
},
|
|
||||||
analysis_saved(data) {
|
|
||||||
// Update "查看完整审查" link behavior
|
|
||||||
},
|
|
||||||
error(data) {
|
|
||||||
showToast('审查失败: ' + (data.message || '未知错误'), 'error');
|
|
||||||
progress.classList.add('hidden');
|
|
||||||
btn.disabled = false;
|
|
||||||
btn.textContent = '🤖 AI 评审';
|
|
||||||
inlineReviewSSE = null;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function cancelInlineReview() {
|
|
||||||
if (inlineReviewSSE) {
|
|
||||||
inlineReviewSSE.abort();
|
|
||||||
inlineReviewSSE = null;
|
|
||||||
}
|
|
||||||
document.getElementById('review-progress').classList.add('hidden');
|
|
||||||
const btn = document.getElementById('btn-inline-review');
|
|
||||||
btn.disabled = false;
|
|
||||||
btn.textContent = '🤖 AI 评审';
|
|
||||||
}
|
|
||||||
|
|
||||||
function insertInlineSuggestions() {
|
function insertInlineSuggestions() {
|
||||||
const fileSeverities = {};
|
const fileSeverities = {};
|
||||||
const severityOrder = { critical: 3, warning: 2, info: 1 };
|
const severityOrder = { critical: 3, warning: 2, info: 1 };
|
||||||
|
|
||||||
inlineSuggestions.forEach((s, i) => {
|
allSuggestions.forEach((s, i) => {
|
||||||
if (s.file) {
|
if (s.file) {
|
||||||
DiffViewer.insertFileSuggestion(s.file, s.severity, s.content, 'inline-sug-' + i);
|
DiffViewer.insertFileSuggestion(s.file, s.severity, s.content, 'sug-' + i);
|
||||||
const cur = fileSeverities[s.file] || 'info';
|
const cur = fileSeverities[s.file] || 'info';
|
||||||
if ((severityOrder[s.severity] || 0) > (severityOrder[cur] || 0)) {
|
if ((severityOrder[s.severity] || 0) > (severityOrder[cur] || 0)) {
|
||||||
fileSeverities[s.file] = s.severity;
|
fileSeverities[s.file] = s.severity;
|
||||||
@@ -746,12 +620,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearInlineReview() {
|
function clearInlineSuggestions() {
|
||||||
const container = document.getElementById('diff-container');
|
const container = document.getElementById('diff-container');
|
||||||
container.querySelectorAll('.file-suggestions-container').forEach(el => el.remove());
|
container.querySelectorAll('.file-suggestions-container').forEach(el => el.remove());
|
||||||
container.querySelectorAll('.file-tree-severity').forEach(el => el.remove());
|
container.querySelectorAll('.file-tree-severity').forEach(el => el.remove());
|
||||||
document.getElementById('review-summary').classList.add('hidden');
|
|
||||||
inlineSuggestions = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Generate PR Description ─────────────────────────────────────
|
// ── Generate PR Description ─────────────────────────────────────
|
||||||
@@ -847,10 +719,9 @@
|
|||||||
document.body.removeChild(textarea);
|
document.body.removeChild(textarea);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Full AI Code Review ─────────────────────────────────────────
|
// ── AI Code Review ─────────────────────────────────────────────
|
||||||
|
|
||||||
let currentSSE = null;
|
let currentSSE = null;
|
||||||
let diffVisible = true;
|
|
||||||
let allSuggestions = [];
|
let allSuggestions = [];
|
||||||
let fileReviews = {};
|
let fileReviews = {};
|
||||||
let currentAnalysisId = null;
|
let currentAnalysisId = null;
|
||||||
@@ -871,7 +742,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const btn = document.getElementById('btn-review');
|
const btn = document.getElementById('btn-review');
|
||||||
const progress = document.getElementById('review-progress-full');
|
const progress = document.getElementById('review-progress');
|
||||||
const results = document.getElementById('review-results');
|
const results = document.getElementById('review-results');
|
||||||
|
|
||||||
btn.disabled = true;
|
btn.disabled = true;
|
||||||
@@ -885,18 +756,16 @@
|
|||||||
currentAnalysisId = null;
|
currentAnalysisId = null;
|
||||||
document.getElementById('summary-content').innerHTML = '';
|
document.getElementById('summary-content').innerHTML = '';
|
||||||
document.getElementById('file-reviews').innerHTML = '';
|
document.getElementById('file-reviews').innerHTML = '';
|
||||||
document.getElementById('review-actions').classList.add('hidden');
|
|
||||||
|
// Clear previous inline suggestions from diff view
|
||||||
|
clearInlineSuggestions();
|
||||||
|
window._reviewDiff = null;
|
||||||
|
|
||||||
// Progress tracking
|
// Progress tracking
|
||||||
let totalFiles = 0;
|
let totalFiles = 0;
|
||||||
let completedFiles = 0;
|
let completedFiles = 0;
|
||||||
let startedFiles = 0;
|
let startedFiles = 0;
|
||||||
|
|
||||||
function updateProgress() {
|
|
||||||
const pct = totalFiles > 0 ? Math.round((completedFiles / totalFiles) * 80 + 10) : 50;
|
|
||||||
document.getElementById('review-progress-bar-full').style.width = pct + '%';
|
|
||||||
}
|
|
||||||
|
|
||||||
const concurrency = document.getElementById('concurrency').value;
|
const concurrency = document.getElementById('concurrency').value;
|
||||||
|
|
||||||
currentSSE = SSE.post(`/api/repos/${repoId}/review`, {
|
currentSSE = SSE.post(`/api/repos/${repoId}/review`, {
|
||||||
@@ -906,13 +775,13 @@
|
|||||||
}, {
|
}, {
|
||||||
start(data) {
|
start(data) {
|
||||||
totalFiles = data.total_files || 0;
|
totalFiles = data.total_files || 0;
|
||||||
document.getElementById('review-progress-text-full').textContent = `准备审查 ${totalFiles} 个文件...`;
|
document.getElementById('review-progress-text').textContent = `准备审查 ${totalFiles} 个文件...`;
|
||||||
document.getElementById('review-progress-bar-full').style.width = '5%';
|
document.getElementById('review-progress-bar').style.width = '5%';
|
||||||
},
|
},
|
||||||
file_start(data) {
|
file_start(data) {
|
||||||
startedFiles++;
|
startedFiles++;
|
||||||
const currentFile = data.file || '';
|
const currentFile = data.file || '';
|
||||||
document.getElementById('review-progress-text-full').textContent = `正在审查: ${currentFile} (${startedFiles}/${totalFiles})`;
|
document.getElementById('review-progress-text').textContent = `正在审查: ${currentFile} (${startedFiles}/${totalFiles})`;
|
||||||
|
|
||||||
if (!fileReviews[currentFile]) {
|
if (!fileReviews[currentFile]) {
|
||||||
fileReviews[currentFile] = { filename: currentFile, suggestions: [], summary: '' };
|
fileReviews[currentFile] = { filename: currentFile, suggestions: [], summary: '' };
|
||||||
@@ -929,8 +798,9 @@
|
|||||||
},
|
},
|
||||||
file_end(data) {
|
file_end(data) {
|
||||||
completedFiles++;
|
completedFiles++;
|
||||||
updateProgress();
|
const pct = totalFiles > 0 ? Math.round((completedFiles / totalFiles) * 80 + 10) : 50;
|
||||||
document.getElementById('review-progress-text-full').textContent = `已完成 ${completedFiles}/${totalFiles} 个文件`;
|
document.getElementById('review-progress-bar').style.width = pct + '%';
|
||||||
|
document.getElementById('review-progress-text').textContent = `已完成 ${completedFiles}/${totalFiles} 个文件`;
|
||||||
},
|
},
|
||||||
file_summary(data) {
|
file_summary(data) {
|
||||||
if (data.file && fileReviews[data.file]) {
|
if (data.file && fileReviews[data.file]) {
|
||||||
@@ -949,25 +819,41 @@
|
|||||||
} else {
|
} else {
|
||||||
el.innerHTML = renderMarkdown(data.content || '');
|
el.innerHTML = renderMarkdown(data.content || '');
|
||||||
}
|
}
|
||||||
document.getElementById('review-progress-bar-full').style.width = '90%';
|
document.getElementById('review-progress-bar').style.width = '90%';
|
||||||
document.getElementById('review-progress-text-full').textContent = '生成总结...';
|
document.getElementById('review-progress-text').textContent = '生成总结...';
|
||||||
},
|
},
|
||||||
done() {
|
done() {
|
||||||
document.getElementById('review-progress-bar-full').style.width = '100%';
|
document.getElementById('review-progress-bar').style.width = '100%';
|
||||||
document.getElementById('review-progress-text-full').textContent = '审查完成!';
|
document.getElementById('review-progress-text').textContent = '审查完成!';
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
progress.classList.add('hidden');
|
progress.classList.add('hidden');
|
||||||
results.classList.remove('hidden');
|
results.classList.remove('hidden');
|
||||||
document.getElementById('review-actions').classList.remove('hidden');
|
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = '开始审查';
|
btn.textContent = '开始审查';
|
||||||
updatePrintHeader();
|
updatePrintHeader();
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
// Render inline suggestions if diff is available
|
// Insert suggestions into the Diff tab's diff view
|
||||||
if (window._reviewDiff) {
|
if (window._reviewDiff) {
|
||||||
renderInlineReview(window._reviewDiff);
|
DiffViewer.init('diff-container');
|
||||||
|
DiffViewer.renderDiff(window._reviewDiff, {
|
||||||
|
onComplete() {
|
||||||
|
insertInlineSuggestions();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Diff not streamed; fetch it and render
|
||||||
|
fetch(`/api/repos/${repoId}/diff?base=${encodeURIComponent(base)}&head=${encodeURIComponent(head)}`, { credentials: 'same-origin' })
|
||||||
|
.then(r => r.json())
|
||||||
|
.then(d => {
|
||||||
|
if (d.diff) {
|
||||||
|
DiffViewer.init('diff-container');
|
||||||
|
DiffViewer.renderDiff(d.diff, {
|
||||||
|
onComplete() { insertInlineSuggestions(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSSE = null;
|
currentSSE = null;
|
||||||
@@ -989,6 +875,17 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cancelReview() {
|
||||||
|
if (currentSSE) {
|
||||||
|
currentSSE.abort();
|
||||||
|
currentSSE = null;
|
||||||
|
}
|
||||||
|
document.getElementById('review-progress').classList.add('hidden');
|
||||||
|
const btn = document.getElementById('btn-review');
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.textContent = '开始审查';
|
||||||
|
}
|
||||||
|
|
||||||
function appendSuggestionCard(suggestion) {
|
function appendSuggestionCard(suggestion) {
|
||||||
const container = document.getElementById('file-reviews');
|
const container = document.getElementById('file-reviews');
|
||||||
|
|
||||||
@@ -1025,41 +922,6 @@
|
|||||||
return (str || '').replace(/[^a-zA-Z0-9]/g, '-');
|
return (str || '').replace(/[^a-zA-Z0-9]/g, '-');
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderInlineReview(diffString) {
|
|
||||||
const container = document.getElementById('review-diff-container');
|
|
||||||
if (!container) return;
|
|
||||||
|
|
||||||
DiffViewer.init('review-diff-container');
|
|
||||||
DiffViewer.renderDiff(diffString, {
|
|
||||||
onComplete() {
|
|
||||||
const fileSeverities = {};
|
|
||||||
const severityOrder = { critical: 3, warning: 2, info: 1 };
|
|
||||||
|
|
||||||
allSuggestions.forEach((s, i) => {
|
|
||||||
if (s.file) {
|
|
||||||
DiffViewer.insertFileSuggestion(s.file, s.severity, s.content, 'sug-' + i);
|
|
||||||
const cur = fileSeverities[s.file] || 'info';
|
|
||||||
if ((severityOrder[s.severity] || 0) > (severityOrder[cur] || 0)) {
|
|
||||||
fileSeverities[s.file] = s.severity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Object.entries(fileSeverities).forEach(([file, sev]) => {
|
|
||||||
DiffViewer.markFileSeverity(file, sev);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleDiffView() {
|
|
||||||
const container = document.getElementById('review-diff-container');
|
|
||||||
const btn = document.getElementById('btn-toggle-diff');
|
|
||||||
diffVisible = !diffVisible;
|
|
||||||
container.style.display = diffVisible ? '' : 'none';
|
|
||||||
btn.textContent = diffVisible ? '隐藏 Diff' : '显示 Diff';
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePrintHeader() {
|
function updatePrintHeader() {
|
||||||
const baseEl = document.getElementById('select-base');
|
const baseEl = document.getElementById('select-base');
|
||||||
const headEl = document.getElementById('select-head');
|
const headEl = document.getElementById('select-head');
|
||||||
@@ -1143,7 +1005,7 @@
|
|||||||
document.getElementById('review-actions').classList.remove('hidden');
|
document.getElementById('review-actions').classList.remove('hidden');
|
||||||
updatePrintHeader();
|
updatePrintHeader();
|
||||||
|
|
||||||
// Load diff and render inline
|
// Load diff and render with inline suggestions in Diff tab
|
||||||
const base = data.base_ref;
|
const base = data.base_ref;
|
||||||
const head = data.head_ref;
|
const head = data.head_ref;
|
||||||
|
|
||||||
@@ -1152,7 +1014,12 @@
|
|||||||
const diffData = await diffResp.json();
|
const diffData = await diffResp.json();
|
||||||
const diffString = diffData.diff || '';
|
const diffString = diffData.diff || '';
|
||||||
if (diffString) {
|
if (diffString) {
|
||||||
renderInlineReview(diffString);
|
DiffViewer.init('diff-container');
|
||||||
|
DiffViewer.renderDiff(diffString, {
|
||||||
|
onComplete() {
|
||||||
|
insertInlineSuggestions();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user