From 58d2e20274e0cff89c416aac14102a34fec35d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E6=98=8E?= <83812544+Ed1s0nZ@users.noreply.github.com> Date: Tue, 21 Apr 2026 21:44:12 +0800 Subject: [PATCH] Add files via upload --- web/static/css/style.css | 94 +++++++++++++++++++++++++++++++++++++++ web/static/js/settings.js | 16 +++++-- web/templates/index.html | 16 ++++--- 3 files changed, 117 insertions(+), 9 deletions(-) diff --git a/web/static/css/style.css b/web/static/css/style.css index 46d0ba03..bdd44f14 100644 --- a/web/static/css/style.css +++ b/web/static/css/style.css @@ -3590,6 +3590,83 @@ header { margin-bottom: 32px; } +.mcp-management-layout { + display: grid; + grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); + gap: 16px; + align-items: stretch; + height: calc(100vh - 210px); + min-height: 520px; + max-height: calc(100vh - 210px); +} + +.mcp-management-panel { + margin-bottom: 0 !important; + padding: 14px 16px 16px; + border: 1px solid var(--border-color); + border-radius: 12px; + background: var(--bg-primary); + display: flex; + flex-direction: column; + min-height: 0; +} + +.mcp-tools-panel { + min-width: 0; + order: 2; +} + +.mcp-external-panel { + min-width: 0; + order: 1; +} + +.mcp-panel-body { + display: flex; + flex-direction: column; + flex: 1; + min-height: 0; +} + +.mcp-tools-panel .tools-controls, +.mcp-external-panel .external-mcp-controls { + flex: 1; + min-height: 0; +} + +.mcp-tools-panel .tools-list { + flex: 1; + min-height: 0; + max-height: 100%; + overflow-y: auto; +} + +.mcp-tools-panel .tools-list-items { + max-height: none; + overflow: visible; +} + +.mcp-external-panel .external-mcp-list { + flex: 1; + min-height: 0; + overflow-y: auto; + padding-right: 4px; +} + +.mcp-external-panel .external-mcp-controls { + gap: 12px; +} + +/* MCP 双栏内工具操作条允许换行,避免面板内溢出 */ +.mcp-tools-panel .tools-actions { + flex-wrap: wrap; + row-gap: 8px; +} + +.mcp-tools-panel .search-box { + min-width: min(280px, 100%); +} + .settings-section:last-child { margin-bottom: 0; } @@ -5396,6 +5473,23 @@ header { /* 响应式优化 */ @media (max-width: 768px) { + .mcp-management-layout { + grid-template-columns: 1fr; + height: auto; + min-height: auto; + max-height: none; + } + + .mcp-management-panel { + min-height: 0; + } + + .mcp-tools-panel .tools-list, + .mcp-external-panel .external-mcp-list { + min-height: 200px; + max-height: 52vh; + } + .tools-actions { gap: 6px; } diff --git a/web/static/js/settings.js b/web/static/js/settings.js index 4dd39ce8..cffa8684 100644 --- a/web/static/js/settings.js +++ b/web/static/js/settings.js @@ -519,7 +519,7 @@ function renderToolsList() { toolItem.innerHTML = ` -
+
${escapeHtml(tool.name)} ${externalBadge} @@ -529,6 +529,11 @@ function renderToolsList() {
`; + toolItem.addEventListener('click', function (event) { + const infoEl = toolItem.querySelector('.tool-item-info'); + if (!infoEl) return; + toggleToolDetail(infoEl, toolKey, !!tool.is_external, tool.external_mcp || '', event); + }); listContainer.appendChild(toolItem); }); @@ -543,14 +548,16 @@ function renderToolsList() { // 展开/折叠工具详情面板(按需从后端加载 schema) function toggleToolDetail(infoEl, toolKey, isExternal, externalMcp, event) { // 点击 checkbox 或外部工具徽章时不展开 - if (event.target.tagName === 'INPUT' || event.target.closest('.external-tool-badge')) return; + if (event && (event.target.tagName === 'INPUT' || event.target.closest('.external-tool-badge'))) return; const detail = infoEl.querySelector('.tool-item-detail'); const icon = infoEl.querySelector('.tool-expand-icon'); if (!detail) return; - const isOpen = detail.style.display !== 'none'; + // 使用 data-open 作为主状态,避免仅依赖 style.display 带来的首击偶发判定不一致 + const isOpen = detail.dataset.open === '1'; detail.style.display = isOpen ? 'none' : 'block'; + detail.dataset.open = isOpen ? '0' : '1'; if (icon) icon.textContent = isOpen ? '▶' : '▼'; // 首次展开时从后端按需加载 @@ -1466,12 +1473,15 @@ async function pollExternalMCPToolCount(name, maxAttempts = 10) { function renderExternalMCPList(servers) { const list = document.getElementById('external-mcp-list'); if (!list) return; + const layout = document.querySelector('.mcp-management-layout'); if (Object.keys(servers).length === 0) { + if (layout) layout.classList.add('external-empty'); const emptyT = typeof window.t === 'function' ? window.t : (k) => k; list.innerHTML = '
📋 ' + emptyT('mcp.noExternalMCP') + '
' + emptyT('mcp.clickToAddExternal') + '
'; return; } + if (layout) layout.classList.remove('external-empty'); let html = '
'; for (const [name, server] of Object.entries(servers)) { diff --git a/web/templates/index.html b/web/templates/index.html index 239c292e..36606126 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -735,17 +735,17 @@

MCP 管理

-
+
-
+

MCP 工具配置

-
+
@@ -765,15 +765,19 @@
-
-

外部 MCP 配置

-
+
+
+

外部 MCP 配置

+ +
+
+