feat: 添加 Toast 通知系统,替换所有 alert() 调用
This commit is contained in:
@@ -152,7 +152,7 @@ const NoteEditor = {
|
|||||||
*/
|
*/
|
||||||
async exportPDF() {
|
async exportPDF() {
|
||||||
if (!this.analysisId) {
|
if (!this.analysisId) {
|
||||||
alert('请先完成审查再导出 PDF');
|
showToast('请先完成审查再导出 PDF', 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ const NoteEditor = {
|
|||||||
document.body.removeChild(a);
|
document.body.removeChild(a);
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
alert('PDF 导出失败: ' + err.message);
|
showToast('PDF 导出失败: ' + err.message, 'error');
|
||||||
} finally {
|
} finally {
|
||||||
if (btn) {
|
if (btn) {
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
|
|||||||
@@ -6,6 +6,48 @@
|
|||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
<script src="/static/js/htmx.min.js"></script>
|
<script src="/static/js/htmx.min.js"></script>
|
||||||
|
<style>
|
||||||
|
.toast-enter { transform: translateX(100%); opacity: 0; }
|
||||||
|
.toast-active { transform: translateX(0); opacity: 1; transition: transform 0.3s ease, opacity 0.3s ease; }
|
||||||
|
.toast-exit { transform: translateX(100%); opacity: 0; transition: transform 0.3s ease, opacity 0.3s ease; }
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
// Global toast notification system
|
||||||
|
(function() {
|
||||||
|
function ensureContainer() {
|
||||||
|
var c = document.getElementById('toast-container');
|
||||||
|
if (!c) {
|
||||||
|
c = document.createElement('div');
|
||||||
|
c.id = 'toast-container';
|
||||||
|
c.className = 'fixed top-4 right-4 z-50 flex flex-col items-end space-y-2';
|
||||||
|
document.body.appendChild(c);
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
window.showToast = function(message, type) {
|
||||||
|
type = type || 'info';
|
||||||
|
var colors = {
|
||||||
|
success: 'bg-green-50 border-green-200 text-green-800',
|
||||||
|
error: 'bg-red-50 border-red-200 text-red-800',
|
||||||
|
info: 'bg-blue-50 border-blue-200 text-blue-800',
|
||||||
|
warning: 'bg-yellow-50 border-yellow-200 text-yellow-800'
|
||||||
|
};
|
||||||
|
var icons = { success: '✓', error: '✗', info: 'ℹ', warning: '⚠' };
|
||||||
|
var container = ensureContainer();
|
||||||
|
var el = document.createElement('div');
|
||||||
|
el.className = 'px-4 py-3 rounded-md border text-sm shadow-lg max-w-sm toast-enter ' + (colors[type] || colors.info);
|
||||||
|
el.innerHTML = '<span class="mr-2 font-bold">' + (icons[type] || icons.info) + '</span>' +
|
||||||
|
'<span>' + message + '</span>' +
|
||||||
|
'<button onclick="this.parentElement.remove()" class="ml-3 text-current opacity-50 hover:opacity-100">×</button>';
|
||||||
|
container.appendChild(el);
|
||||||
|
requestAnimationFrame(function() { el.className = el.className.replace('toast-enter', 'toast-active'); });
|
||||||
|
setTimeout(function() {
|
||||||
|
el.className = el.className.replace('toast-active', 'toast-exit');
|
||||||
|
setTimeout(function() { el.remove(); }, 300);
|
||||||
|
}, 4000);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|||||||
@@ -191,7 +191,7 @@
|
|||||||
const headRef = document.getElementById('head-ref').value;
|
const headRef = document.getElementById('head-ref').value;
|
||||||
|
|
||||||
if (!baseRef || !headRef) {
|
if (!baseRef || !headRef) {
|
||||||
alert('请选择 Base 和 Head 分支');
|
showToast('请选择 Base 和 Head 分支', 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
btn.textContent = '生成 PR 描述';
|
btn.textContent = '生成 PR 描述';
|
||||||
},
|
},
|
||||||
error(data) {
|
error(data) {
|
||||||
alert('生成失败: ' + (data.message || '未知错误'));
|
showToast('生成失败: ' + (data.message || '未知错误'), 'error');
|
||||||
streaming.classList.add('hidden');
|
streaming.classList.add('hidden');
|
||||||
output.classList.add('hidden');
|
output.classList.add('hidden');
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
@@ -275,7 +275,7 @@
|
|||||||
function copyMarkdown() {
|
function copyMarkdown() {
|
||||||
const markdown = markdownContent || document.getElementById('pr-markdown').textContent;
|
const markdown = markdownContent || document.getElementById('pr-markdown').textContent;
|
||||||
navigator.clipboard.writeText(markdown).then(() => {
|
navigator.clipboard.writeText(markdown).then(() => {
|
||||||
alert('已复制到剪贴板');
|
showToast('已复制到剪贴板', 'success');
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
const textarea = document.createElement('textarea');
|
const textarea = document.createElement('textarea');
|
||||||
textarea.value = markdown;
|
textarea.value = markdown;
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
textarea.select();
|
textarea.select();
|
||||||
document.execCommand('copy');
|
document.execCommand('copy');
|
||||||
document.body.removeChild(textarea);
|
document.body.removeChild(textarea);
|
||||||
alert('已复制到剪贴板');
|
showToast('已复制到剪贴板', 'success');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -405,7 +405,7 @@
|
|||||||
const base = document.getElementById('select-base').value;
|
const base = document.getElementById('select-base').value;
|
||||||
const head = document.getElementById('select-head').value;
|
const head = document.getElementById('select-head').value;
|
||||||
if (!base || !head) {
|
if (!base || !head) {
|
||||||
alert('请选择 Base 和 Head 分支');
|
showToast('请选择 Base 和 Head 分支', 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DiffViewer.loadDiff(repoId, base, head);
|
DiffViewer.loadDiff(repoId, base, head);
|
||||||
@@ -436,7 +436,7 @@
|
|||||||
const base = document.getElementById('select-base').value;
|
const base = document.getElementById('select-base').value;
|
||||||
const head = document.getElementById('select-head').value;
|
const head = document.getElementById('select-head').value;
|
||||||
if (!base || !head) {
|
if (!base || !head) {
|
||||||
alert('请先选择 Base 和 Head 并查看 Diff');
|
showToast('请先选择 Base 和 Head 并查看 Diff', 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -499,7 +499,7 @@
|
|||||||
viewLink.href = `/repo/${repoId}/review?base=${encodeURIComponent(base)}&head=${encodeURIComponent(head)}`;
|
viewLink.href = `/repo/${repoId}/review?base=${encodeURIComponent(base)}&head=${encodeURIComponent(head)}`;
|
||||||
},
|
},
|
||||||
error(data) {
|
error(data) {
|
||||||
alert('审查失败: ' + (data.message || '未知错误'));
|
showToast('审查失败: ' + (data.message || '未知错误'), 'error');
|
||||||
progress.classList.add('hidden');
|
progress.classList.add('hidden');
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = '🤖 AI 评审';
|
btn.textContent = '🤖 AI 评审';
|
||||||
|
|||||||
@@ -229,7 +229,7 @@
|
|||||||
const topN = document.getElementById('top-n').value;
|
const topN = document.getElementById('top-n').value;
|
||||||
|
|
||||||
if (!baseRef || !headRef) {
|
if (!baseRef || !headRef) {
|
||||||
alert('请选择 Base 和 Head 分支');
|
showToast('请选择 Base 和 Head 分支', 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +340,7 @@
|
|||||||
NoteEditor.loadNotes();
|
NoteEditor.loadNotes();
|
||||||
},
|
},
|
||||||
error(data) {
|
error(data) {
|
||||||
alert('审查失败: ' + (data.message || '未知错误'));
|
showToast('审查失败: ' + (data.message || '未知错误'), 'error');
|
||||||
progress.classList.add('hidden');
|
progress.classList.add('hidden');
|
||||||
btn.disabled = false;
|
btn.disabled = false;
|
||||||
btn.textContent = '开始审查';
|
btn.textContent = '开始审查';
|
||||||
@@ -471,7 +471,7 @@
|
|||||||
|
|
||||||
const result = data.result;
|
const result = data.result;
|
||||||
if (!result || !result.file_reviews) {
|
if (!result || !result.file_reviews) {
|
||||||
alert('该历史记录没有完整的评审数据');
|
showToast('该历史记录没有完整的评审数据', 'warning');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,7 +533,7 @@
|
|||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Load history error:', e);
|
console.error('Load history error:', e);
|
||||||
alert('加载历史评审失败: ' + e.message);
|
showToast('加载历史评审失败: ' + e.message, 'error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user