Add files via upload

This commit is contained in:
公明
2025-11-25 21:24:03 +08:00
committed by GitHub
parent c60d2fdfcd
commit 48c0232f57
3 changed files with 246 additions and 38 deletions

View File

@@ -449,8 +449,8 @@ header {
.message.system .message-content {
max-width: 90%;
align-items: center;
margin: 0 auto;
align-items: stretch;
margin: 0;
}
.message-bubble {
@@ -611,7 +611,7 @@ header {
background: var(--bg-tertiary);
color: var(--text-secondary);
border: 1px solid var(--border-color);
text-align: center;
text-align: left;
font-size: 0.875rem;
padding: 10px 16px;
width: 100%;
@@ -1148,42 +1148,135 @@ header {
}
.detail-section {
margin-bottom: 24px;
margin-bottom: 20px;
background: var(--bg-primary);
border: 1px solid var(--border-color);
border-radius: 14px;
padding: 20px;
box-shadow: var(--shadow-sm);
}
.detail-section:last-child {
margin-bottom: 0;
}
.detail-section-overview {
background: linear-gradient(135deg, rgba(0, 102, 255, 0.07), rgba(0, 102, 255, 0.02));
border-color: rgba(0, 102, 255, 0.2);
}
.detail-section-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 16px;
}
.detail-section h3 {
margin: 0;
color: var(--text-primary);
margin-bottom: 12px;
padding-bottom: 8px;
border-bottom: 1px solid var(--border-color);
font-size: 0.9375rem;
font-size: 1rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.detail-info-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 14px;
}
.detail-info-grid .detail-item {
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 12px;
padding: 12px 14px;
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.02);
}
.detail-item {
margin-bottom: 10px;
padding: 8px 0;
display: flex;
align-items: baseline;
gap: 8px;
flex-direction: column;
gap: 6px;
margin: 0;
}
.detail-item strong {
color: var(--text-secondary);
font-weight: 500;
font-size: 0.875rem;
min-width: 80px;
font-weight: 600;
font-size: 0.75rem;
letter-spacing: 0.5px;
text-transform: uppercase;
}
.detail-item span {
color: var(--text-primary);
font-size: 0.875rem;
font-size: 0.95rem;
font-weight: 600;
word-break: break-word;
}
.mono-text {
font-family: 'SF Mono', 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
font-size: 0.85rem;
color: var(--text-secondary);
}
.status-chip {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 4px 12px;
border-radius: 999px;
font-size: 0.8125rem;
font-weight: 600;
background: var(--bg-tertiary);
color: var(--text-secondary);
border: 1px solid transparent;
text-transform: none;
}
.status-chip.status-running {
background: rgba(0, 102, 255, 0.12);
color: var(--accent-color);
border-color: rgba(0, 102, 255, 0.3);
}
.status-chip.status-completed {
background: rgba(40, 167, 69, 0.12);
color: var(--success-color);
border-color: rgba(40, 167, 69, 0.3);
}
.status-chip.status-failed {
background: rgba(220, 53, 69, 0.12);
color: var(--error-color);
border-color: rgba(220, 53, 69, 0.3);
}
.status-chip.status-pending,
.status-chip.status-unknown {
background: rgba(255, 193, 7, 0.12);
color: #b8860b;
border-color: rgba(255, 193, 7, 0.3);
}
.detail-code-card {
background: var(--bg-secondary);
border: 1px dashed rgba(0, 0, 0, 0.06);
border-radius: 12px;
padding: 12px;
}
.detail-code-card .code-block {
margin: 0;
max-height: 360px;
}
.detail-error-wrapper {
border-color: rgba(220, 53, 69, 0.4);
background: rgba(220, 53, 69, 0.05);
}
.code-block {
@@ -1208,6 +1301,24 @@ header {
color: var(--error-color);
}
.btn-ghost {
padding: 6px 14px;
border-radius: 999px;
background: transparent;
border: 1px solid transparent;
color: var(--accent-color);
font-size: 0.8125rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-ghost:hover {
background: rgba(0, 102, 255, 0.08);
border-color: rgba(0, 102, 255, 0.2);
color: var(--accent-hover);
}
/* 滚动条样式 */
::-webkit-scrollbar {
width: 8px;

View File

@@ -829,8 +829,13 @@ async function showMCPDetail(executionId) {
// 填充模态框内容
document.getElementById('detail-tool-name').textContent = exec.toolName || 'Unknown';
document.getElementById('detail-execution-id').textContent = exec.id || 'N/A';
document.getElementById('detail-status').textContent = getStatusText(exec.status);
document.getElementById('detail-time').textContent = new Date(exec.startTime).toLocaleString('zh-CN');
const statusEl = document.getElementById('detail-status');
const normalizedStatus = (exec.status || 'unknown').toLowerCase();
statusEl.textContent = getStatusText(exec.status);
statusEl.className = `status-chip status-${normalizedStatus}`;
document.getElementById('detail-time').textContent = exec.startTime
? new Date(exec.startTime).toLocaleString('zh-CN')
: '—';
// 请求参数
const requestData = {
@@ -874,6 +879,75 @@ function closeMCPDetail() {
document.getElementById('mcp-detail-modal').style.display = 'none';
}
// 复制详情面板中的内容
function copyDetailBlock(elementId, triggerBtn = null) {
const target = document.getElementById(elementId);
if (!target) {
return;
}
const text = target.textContent || '';
if (!text.trim()) {
return;
}
const originalLabel = triggerBtn ? (triggerBtn.dataset.originalLabel || triggerBtn.textContent.trim()) : '';
if (triggerBtn && !triggerBtn.dataset.originalLabel) {
triggerBtn.dataset.originalLabel = originalLabel;
}
const showCopiedState = () => {
if (!triggerBtn) {
return;
}
triggerBtn.textContent = '已复制';
triggerBtn.disabled = true;
setTimeout(() => {
triggerBtn.disabled = false;
triggerBtn.textContent = triggerBtn.dataset.originalLabel || originalLabel || '复制';
}, 1200);
};
const fallbackCopy = (value) => {
return new Promise((resolve, reject) => {
const textarea = document.createElement('textarea');
textarea.value = value;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.focus();
textarea.select();
try {
const successful = document.execCommand('copy');
document.body.removeChild(textarea);
if (successful) {
resolve();
} else {
reject(new Error('execCommand failed'));
}
} catch (err) {
document.body.removeChild(textarea);
reject(err);
}
});
};
const copyPromise = (navigator.clipboard && typeof navigator.clipboard.writeText === 'function')
? navigator.clipboard.writeText(text)
: fallbackCopy(text);
copyPromise
.then(() => {
showCopiedState();
})
.catch(() => {
if (triggerBtn) {
triggerBtn.disabled = false;
triggerBtn.textContent = triggerBtn.dataset.originalLabel || originalLabel || '复制';
}
alert('复制失败,请手动选择文本复制。');
});
}
// 开始新对话
function startNewConversation() {

View File

@@ -237,32 +237,55 @@
<span class="modal-close" onclick="closeMCPDetail()">&times;</span>
</div>
<div class="modal-body">
<div class="detail-section">
<h3>执行信息</h3>
<div class="detail-item">
<strong>工具:</strong> <span id="detail-tool-name"></span>
<div class="detail-section detail-section-overview">
<div class="detail-section-header">
<h3>执行信息</h3>
</div>
<div class="detail-item">
<strong>状态:</strong> <span id="detail-status"></span>
</div>
<div class="detail-item">
<strong>时间:</strong> <span id="detail-time"></span>
</div>
<div class="detail-item">
<strong>ID:</strong> <span id="detail-execution-id" style="font-family: monospace; font-size: 0.8125rem; color: var(--text-secondary);"></span>
<div class="detail-info-grid">
<div class="detail-item">
<strong>工具</strong>
<span id="detail-tool-name"></span>
</div>
<div class="detail-item">
<strong>状态</strong>
<span id="detail-status" class="status-chip status-unknown"></span>
</div>
<div class="detail-item">
<strong>时间</strong>
<span id="detail-time"></span>
</div>
<div class="detail-item">
<strong>执行 ID</strong>
<span id="detail-execution-id" class="mono-text"></span>
</div>
</div>
</div>
<div class="detail-section">
<h3>请求参数</h3>
<pre id="detail-request" class="code-block"></pre>
<div class="detail-section-header">
<h3>请求参数</h3>
<button class="btn-ghost" type="button" onclick="copyDetailBlock('detail-request', this)">复制 JSON</button>
</div>
<div class="detail-code-card">
<pre id="detail-request" class="code-block"></pre>
</div>
</div>
<div class="detail-section">
<h3>响应结果</h3>
<pre id="detail-response" class="code-block"></pre>
<div class="detail-section-header">
<h3>响应结果</h3>
<button class="btn-ghost" type="button" onclick="copyDetailBlock('detail-response', this)">复制内容</button>
</div>
<div class="detail-code-card">
<pre id="detail-response" class="code-block"></pre>
</div>
</div>
<div class="detail-section" id="detail-error-section" style="display: none;">
<h3>错误信息</h3>
<pre id="detail-error" class="code-block error"></pre>
<div class="detail-section detail-error-wrapper" id="detail-error-section" style="display: none;">
<div class="detail-section-header">
<h3>错误信息</h3>
<button class="btn-ghost" type="button" onclick="copyDetailBlock('detail-error', this)">复制错误</button>
</div>
<div class="detail-code-card">
<pre id="detail-error" class="code-block error"></pre>
</div>
</div>
</div>
</div>