127 lines
4.6 KiB
JavaScript
127 lines
4.6 KiB
JavaScript
// Review Inline: renders AI review suggestions inline in a diff view
|
|
const ReviewInline = {
|
|
suggestions: [],
|
|
|
|
init(diffContainerId, suggestionsContainerId) {
|
|
this.diffContainer = document.getElementById(diffContainerId);
|
|
this.suggestionsContainer = document.getElementById(suggestionsContainerId);
|
|
this.suggestions = [];
|
|
},
|
|
|
|
// Add a suggestion to the collection
|
|
addSuggestion(suggestion) {
|
|
this.suggestions.push(suggestion);
|
|
},
|
|
|
|
// Render all collected suggestions inline in the diff
|
|
renderInline() {
|
|
if (!this.diffContainer) return;
|
|
|
|
this.suggestions.forEach((s, index) => {
|
|
DiffViewer.insertSuggestion(
|
|
s.file,
|
|
s.line,
|
|
s.side || 'right',
|
|
s.severity || 'info',
|
|
s.content || '',
|
|
`suggestion-${index}`
|
|
);
|
|
});
|
|
},
|
|
|
|
// Render a single suggestion card (for the card-based view)
|
|
renderSuggestionCard(suggestion) {
|
|
const severityStyles = {
|
|
critical: {
|
|
border: 'border-l-4 border-red-500',
|
|
bg: 'bg-red-50',
|
|
badge: 'bg-red-100 text-red-800',
|
|
icon: '🔴',
|
|
label: '严重',
|
|
},
|
|
warning: {
|
|
border: 'border-l-4 border-yellow-500',
|
|
bg: 'bg-yellow-50',
|
|
badge: 'bg-yellow-100 text-yellow-800',
|
|
icon: '🟡',
|
|
label: '建议',
|
|
},
|
|
info: {
|
|
border: 'border-l-4 border-green-500',
|
|
bg: 'bg-green-50',
|
|
badge: 'bg-green-100 text-green-800',
|
|
icon: '🟢',
|
|
label: '提示',
|
|
},
|
|
};
|
|
|
|
const style = severityStyles[suggestion.severity] || severityStyles.info;
|
|
|
|
return `
|
|
<div class="review-card ${style.border} ${style.bg} rounded-lg p-4 mb-3">
|
|
<div class="flex items-center gap-2 mb-2">
|
|
<span class="${style.badge} px-2 py-0.5 rounded text-xs font-medium">
|
|
${style.icon} ${style.label}
|
|
</span>
|
|
${suggestion.file ? `<span class="text-xs text-gray-500 font-mono">${suggestion.file}</span>` : ''}
|
|
${suggestion.line ? `<span class="text-xs text-gray-400">行 ${suggestion.line}</span>` : ''}
|
|
</div>
|
|
<div class="text-sm text-gray-700 review-content">${typeof renderMarkdown === 'function' ? renderMarkdown(suggestion.content || '') : (suggestion.content || '')}</div>
|
|
${suggestion.code_example ? `
|
|
<pre class="mt-2 p-2 bg-gray-100 rounded text-xs overflow-x-auto"><code>${this._escapeHtml(suggestion.code_example)}</code></pre>
|
|
` : ''}
|
|
</div>`;
|
|
},
|
|
|
|
// Render file review section
|
|
renderFileReview(fileReview) {
|
|
const severityOrder = { critical: 0, warning: 1, info: 2 };
|
|
const suggestions = (fileReview.suggestions || []).sort((a, b) =>
|
|
(severityOrder[a.severity] || 2) - (severityOrder[b.severity] || 2)
|
|
);
|
|
|
|
const maxSeverity = suggestions.length > 0 ? suggestions[0].severity : 'info';
|
|
const severityColors = {
|
|
critical: 'border-red-500',
|
|
warning: 'border-yellow-500',
|
|
info: 'border-green-500',
|
|
};
|
|
|
|
let html = `
|
|
<div class="file-review bg-white rounded-lg shadow-md ${severityColors[maxSeverity] || ''} border-l-4 mb-4">
|
|
<div class="p-4 border-b border-gray-100">
|
|
<h3 class="font-medium text-gray-900 font-mono text-sm">${fileReview.filename || ''}</h3>
|
|
${fileReview.summary ? `<p class="text-sm text-gray-600 mt-1">${fileReview.summary}</p>` : ''}
|
|
</div>
|
|
<div class="p-4 space-y-3">`;
|
|
|
|
suggestions.forEach(s => {
|
|
html += this.renderSuggestionCard(s);
|
|
});
|
|
|
|
html += `
|
|
</div>
|
|
</div>`;
|
|
|
|
return html;
|
|
},
|
|
|
|
// Render overall summary
|
|
renderSummary(summary) {
|
|
if (!summary) return '';
|
|
return `
|
|
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
|
|
<h2 class="text-lg font-semibold text-gray-900 mb-3">整体评估</h2>
|
|
<div class="prose text-sm text-gray-700">${summary}</div>
|
|
</div>`;
|
|
},
|
|
|
|
_escapeHtml(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
};
|
|
|
|
window.ReviewInline = ReviewInline;
|