diff --git a/config.yaml b/config.yaml index c9ec2226..f9e88edd 100644 --- a/config.yaml +++ b/config.yaml @@ -47,5 +47,4 @@ security: # 系统会从该目录加载所有 .yaml 格式的工具配置文件 # 推荐方式:在 tools/ 目录下为每个工具创建独立的配置文件 # 外部MCP配置 -external_mcp: - \ No newline at end of file +external_mcp: \ No newline at end of file diff --git a/web/static/css/style.css b/web/static/css/style.css index ed5601a7..a727fc51 100644 --- a/web/static/css/style.css +++ b/web/static/css/style.css @@ -1527,6 +1527,7 @@ header { align-items: center; flex-wrap: nowrap; width: 100%; + overflow: visible; } .tools-actions button { @@ -1538,6 +1539,8 @@ header { font-size: 0.875rem; cursor: pointer; transition: all 0.2s; + flex-shrink: 0; + white-space: nowrap; } .tools-actions button:hover { @@ -1559,11 +1562,49 @@ header { display: flex; gap: 4px; flex: 1; - min-width: 0; - max-width: 300px; + min-width: 150px; align-items: center; } +.page-size-selector { + display: flex; + align-items: center; + gap: 4px; + flex-shrink: 0; + white-space: nowrap; + margin-right: 8px; +} + +.page-size-selector label { + font-size: 0.8125rem; + color: var(--text-secondary); + white-space: nowrap; + margin-right: 4px; +} + +.page-size-selector select { + padding: 6px 10px; + border: 1px solid var(--border-color); + border-radius: 6px; + background: var(--bg-primary); + color: var(--text-primary); + font-size: 0.8125rem; + cursor: pointer; + transition: all 0.2s; + min-width: 70px; + height: 32px; +} + +.page-size-selector select:focus { + outline: none; + border-color: var(--accent-color); + box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.1); +} + +.page-size-selector select:hover { + border-color: var(--accent-color); +} + .search-box input { flex: 1; padding: 8px 12px; @@ -1688,6 +1729,8 @@ header { border-top: 1px solid var(--border-color); margin-top: 8px; background: var(--bg-primary); + gap: 16px; + flex-wrap: wrap; } .pagination-info { @@ -1718,6 +1761,41 @@ header { padding: 0 8px; } +.pagination-page-size { + display: flex; + align-items: center; + gap: 6px; + flex-shrink: 0; +} + +.pagination-page-size label { + font-size: 0.875rem; + color: var(--text-secondary); + white-space: nowrap; +} + +.pagination-page-size select { + padding: 6px 10px; + border: 1px solid var(--border-color); + border-radius: 6px; + background: var(--bg-primary); + color: var(--text-primary); + font-size: 0.875rem; + cursor: pointer; + transition: all 0.2s; + min-width: 70px; +} + +.pagination-page-size select:focus { + outline: none; + border-color: var(--accent-color); + box-shadow: 0 0 0 2px rgba(0, 102, 255, 0.1); +} + +.pagination-page-size select:hover { + border-color: var(--accent-color); +} + .modal-footer { display: flex; justify-content: flex-end; @@ -2078,25 +2156,26 @@ header { .tools-stats { display: flex; align-items: center; - gap: 15px; + gap: 12px; margin-left: auto; - padding: 8px 16px; + padding: 6px 12px; background: linear-gradient(135deg, var(--bg-secondary) 0%, var(--bg-tertiary) 100%); border: 1px solid var(--border-color); border-radius: 10px; - font-size: 0.8125rem; + font-size: 0.75rem; color: var(--text-secondary); box-shadow: var(--shadow-sm); flex-wrap: nowrap; - flex-shrink: 0; + flex-shrink: 1; white-space: nowrap; + min-width: 0; } .tools-stats span { display: inline-flex; align-items: center; - gap: 8px; - padding: 4px 0; + gap: 6px; + padding: 2px 0; white-space: nowrap; flex-shrink: 0; } @@ -2110,9 +2189,9 @@ header { .tools-stats span:not(:last-child)::after { content: ''; width: 1px; - height: 20px; + height: 16px; background: var(--border-color); - margin-left: 10px; + margin-left: 8px; display: inline-block; } @@ -2392,6 +2471,49 @@ header { /* 响应式优化 */ @media (max-width: 768px) { + .tools-actions { + gap: 6px; + } + + .tools-actions button { + padding: 6px 12px; + font-size: 0.8125rem; + } + + .search-box { + min-width: 100px; + } + + .search-box input { + font-size: 0.8125rem; + padding: 6px 10px; + } + + .btn-search { + padding: 6px 12px; + min-width: 36px; + } + + .page-size-selector { + font-size: 0.75rem; + } + + .page-size-selector select { + padding: 4px 8px; + font-size: 0.75rem; + min-width: 50px; + } + + .tools-stats { + padding: 4px 8px; + font-size: 0.7rem; + gap: 8px; + } + + .tools-stats span { + gap: 4px; + } + .external-mcp-actions { flex-direction: column; align-items: stretch; diff --git a/web/static/js/app.js b/web/static/js/app.js index 8306e27e..de332672 100644 --- a/web/static/js/app.js +++ b/web/static/js/app.js @@ -1688,9 +1688,15 @@ async function cancelActiveTask(conversationId, button) { // 设置相关功能 let currentConfig = null; let allTools = []; +// 从localStorage读取每页显示数量,默认为20 +const getToolsPageSize = () => { + const saved = localStorage.getItem('toolsPageSize'); + return saved ? parseInt(saved, 10) : 20; +}; + let toolsPagination = { page: 1, - pageSize: 20, + pageSize: getToolsPageSize(), total: 0, totalPages: 0 }; @@ -1750,6 +1756,10 @@ async function loadConfig() { // 填充Agent配置 document.getElementById('agent-max-iterations').value = currentConfig.agent.max_iterations || 30; + // 设置每页显示数量(会在分页控件渲染时设置) + const savedPageSize = getToolsPageSize(); + toolsPagination.pageSize = savedPageSize; + // 加载工具列表(使用分页) toolsSearchKeyword = ''; await loadToolsList(1, ''); @@ -1896,10 +1906,20 @@ function renderToolsPagination() { const startItem = (page - 1) * toolsPagination.pageSize + 1; const endItem = Math.min(page * toolsPagination.pageSize, total); + const savedPageSize = getToolsPageSize(); pagination.innerHTML = `
显示 ${startItem}-${endItem} / 共 ${total} 个工具${toolsSearchKeyword ? ` (搜索: "${escapeHtml(toolsSearchKeyword)}")` : ''}
+
+ + +
@@ -1928,6 +1948,33 @@ function deselectAllTools() { updateToolsStats(); } +// 改变每页显示数量 +async function changeToolsPageSize() { + // 尝试从两个位置获取选择器(顶部或分页区域) + const pageSizeSelect = document.getElementById('tools-page-size') || document.getElementById('tools-page-size-pagination'); + if (!pageSizeSelect) return; + + const newPageSize = parseInt(pageSizeSelect.value, 10); + if (isNaN(newPageSize) || newPageSize < 1) { + return; + } + + // 保存到localStorage + localStorage.setItem('toolsPageSize', newPageSize.toString()); + + // 更新分页配置 + toolsPagination.pageSize = newPageSize; + + // 同步更新另一个选择器(如果存在) + const otherSelect = document.getElementById('tools-page-size') || document.getElementById('tools-page-size-pagination'); + if (otherSelect && otherSelect !== pageSizeSelect) { + otherSelect.value = newPageSize; + } + + // 重新加载第一页 + await loadToolsList(1, toolsSearchKeyword); +} + // 更新工具统计信息 async function updateToolsStats() { const statsEl = document.getElementById('tools-stats');